Etckeeper ist eine Software, die andere VCSs nutzt. Zur Auswahl stehen hier:
Die Konfigurationsdatei von etckeeper
befindet sich unter /etc/etckeeper/etckeeper.conf
.
Da die üblichen Versionsverwaltungssysteme keine Dateiberechtigungen und Dateibesitzer speichern wird dies von
etckeeper
in der Datei /etc/.etckeeper
erledigt. Dies ist eine einfache Textdatei, die verändert werden kann. Aber
davon würde ich eher abraten.
Unter Arch Linux gibt es das Paket etckeeper
im AUR.
Nachdem die Software installiert ist, muss das Git-Repository angelegt werden:
# etckeeper init
# git status
Nun können alle Konfigurationsdateien dem Repository hingezufügen werden:
# git add .
# git commit -m "Initial commit"
# git gc # pack git repo to save a lot of space
Falls jemand nicht möchte, dass manche Konfigurationsdateien hinzugefügt werden, kann diese Datei in die
/etc/.gitignore
eintragen.
Ich melde mich immer zuerst als root
an, damit ich nicht immer sudo
vor meine Befehle schreiben muss:
$ su
Danach kann der normale Git-Workflow beibehalten werden, denn es wird nur mit Git gearbeitet.
Erst wenn neue Dateien dem Repository hinzugefügt wurden und commitet wurden, muss man
wieder etckeeper init
ausführen, damit die Metadaten mitgesichert werden.
Anschließend darf man natürlich nicht vergessen, sich vom root
wieder abzumelden über:
# exit
Schön wäre es natürlich noch, wenn andere Konfigurationsdateien, als die, die sich in /etc
befinden, versioniert
werden würden. Dafür habe ich noch keine Lösung gefunden. Aber zur Not könnte man ein Verzeichnis wie /etc/others
erstellen, das symbolische Links oder Hardlinks enthält:
# mkdir -p /etc/others
# ln -s /boot/grub .
Hardlinks funktionieren nur innerhalb einer Partition, also über Festplatten oder Partitionen hinweg nicht.
Das Versionieren von Konfigurationsdateien bringt einige Vorteile:
Ich bin mir der Lösung sehr zufrieden, auch wenn es mir Mehraufwand verbunden ist.
Der Auslöser dieses Umbruchs war mein Smartphone, das vor ein paar Tagen nicht mehr bootete. Als ich dann ein Backup
wiedergeherstellt hatte, das allerdings nicht geklappt hat, musste ich das ROM neuinstallieren.
Dann wurde mir bewusst, dass ich einen Teil meiner Kontakte nicht mehr hatte, sowie alle Termine.
Desweiteren hatte ich Pulse verwendet, welche keine Synchronisierung anbietet. Somit waren auch meine RSS-Feeds weg bzw. der Status des Feeds (gelesen/ungelesen).
Warum habe ich mich nun für Google entschieden, obwohl ich eigentlich sehr auf Datenschutz aus bin?
Deshalb, weil ich es Leid war meine Kontakte, Termine und Aufgaben nicht synchronisiert zu haben. Ich habe dafür schon einige aufgewendet Stunden, um eine brauchbare Lösung ohne Google zu finden. Aber leider habe ich
keine gefunden.
Falls es jedoch eine gibt, dann bitte ich um einen Kommentar oder eine Nachricht.
Ich lese einige Blogs, die ich über RSS-Feeds nutze. Google Reader ermöglicht auch hier das Lesen der Artikel. Außerdem lese ich ab und zu mal an meinem Smartphone oder am Rechner. Auch dies wird nun synchronisiert, sodass ich immer genau weiß, welche Artikel ich gelesen habe und welche noch zu lesen sind.
Als ich Diaspora vor einem Jahr kennen gelernt habe, fand ich es eigentlich gar nicht so schlecht. Der Ansatz und das
Konzept dahinter finde ich super! Aber leider hat es sich seitdem nicht wirklich weiterentwickelt.
Außerdem sind dort sehr viele Leute, die sich mit dem Thema Computer, Internet und dem was dazugehört gut auskennen. Das
ist aber auch ein Problem. All diese Leute sind nicht die Mehrheit der Menschen. Somit befindet man sich in einem stark
eingeschränkten Umfeld. Desweiteren sind fast alle Leute, die ich kenne, nicht dort angemeldet.
Das ist nicht der Sinn eines Sozialen Netzwerks, meiner Meinung nach.
Ich finde es natürlich schade, aber vielleicht tut sich noch etwas in den nächsten Monaten, Jahren,…
Natürlich hat es auch einen Preis, obwohl es kostenlos ist. Man zahlt mit seinen Daten. Ich bin aber der Meinung, dass
Google relativ großen Wert auf Datenschutz legt. Auf jeden Fall viel mehr, als es Facebook tut. (Wobei das auch nicht
schwierig ist!)
Für mich ist es aber auch ein Test, um zu schauen, was mit meinen Daten geschieht. Werden diese an andere Unternehmen
geschickt, was ich nicht hoffe oder wie verändert sich
Natürlich habe ich alle Datenschutz- und Anti-Personalisierungsmöglichkeiten in den Einstellungen getätigt, die zur Verfügung gestellt werden.
Ich finde es gar nicht schlecht, dass man bei Google all seine Daten exportieren kann und in anderen Diensten nutzen kann/könnte. Zudem gibt es die Möglichkeit, dass man sein kompletten Account bei Google, Google+ löschen lassen kann. Dann werden alle Daten mitgelöscht. Ob das intern wirklich gelöscht wird, weiß ich natürlich nicht, aber davon gehe ich mal aus.
Ich bin bis jetzt mit der Lösung des Synchronisationsproblems zufrieden. Mal schauen, wie Google den Datenschutz einhält
und ob ich Probleme damit bekommen werde.
Außerdem würde ich Google sofort verlassen, wenn es eine Open-Source-Lösung dafür gibt.
Was haltet ihr von meinem Schritt? Es gibt bestimmt ein paar unter euch, die mich dafür steinigen würden. Aber vielleicht stimmen andere meinem Schritt zu. Ich freue mich auf Kommentare!
]]>Eine Partitionstabelle beinhaltet alle Informationen zur Partitionierung einer Festplatte. Es wird oft empfohlen den MBR
zu sichern, das ich es auch gemacht habe, aber dieser enthält nur die ersten 4 Partitionen. Bei bootbaren Partitionen
sogar nur den Bootloader. Falls weitere Partitionen eingerichtet sind, muss ein anderes Tool genutzt werden, um die restlichen
Partitionierungen zu sichern. Dabei stieß ich auf das Tool sfdisk
.
Das Tool sfdisk
befindet sich im Paket util-linux
, das bestimmt bei der Installation des Betriebssystems mit
installiert worden ist. Falls das jedoch nicht der Fall war, kann man es entsprechend nachholen.
Das Sichern der Partitionstabelle einer Festplatte ist durch den folgenden Befehl leicht durchgeführt:
# sfdisk -d /dev/sd#
Hinweis: Natürlich gibt es das Device /dev/sd#
nicht. Das #
muss durch einen Buchstaben ersetzt werden. Am besten
man nutzt die Autovervollständigung der Shell.
Die Ausgabe wäre beispielsweise folgende:
“` sh
unit: sectors
/dev/sdb1 : start= 32, size= 133088, Id=fd, bootable /dev/sdb2 : start= 133120, size= 10487808, Id=fd /dev/sdb3 : start= 10620928, size= 41945088, Id=fd /dev/sdb4 : start= 52566016, size= 19120128, Id= f /dev/sdb5 : start= 52566048, size= 4196320, Id=fd /dev/sdb6 : start= 56762400, size= 14923744, Id=fd “`
Quelle: linupedia.org
Diese Ausgabe kann nun in eine Datei geschrieben werden:
# sfdisk -d /dev/sdb > ~/sys/backup/partitiontable_sdb_$(date +%Y-%m-%d_%H-%M).txt
Falls es nun nötig wird, die Partitionstabelle wiederherzustellen, da die alte beispielsweise aus Versehen gelöscht oder verändert wurde, kann man es durch das vorher erstellte Backup tun.
Wichtig: Wenn man sich nicht sicher ist, ob das vorliegende Backup der gesicherten Partitionstabelle entspricht, dann
ist das Retten der Partitionstabelle
vorzuziehen.
Außerdem darf die zu wiederherstellende Festplatte nicht gemountet sein. Am einfachsten würde ich hier ein
Live-Betriebssystem nutzen, das von einem USB-Stick oder von einer CD gestartet wurde.
Das Wiederherstellen geschieht mit dem folgenden Befehl:
# sfdisk /dev/sdb < ~/sys/backup/partitiontable_sdb_2012-07-12_12-36.txt
Zum Glück ist es mir noch nicht passiert, dass ich eine Partitionstabelle wiederherstellen musste. Aber nun bin ich auf
der sicheren Seite.
Welche weiteren Daten werden von euch zusätzlich gesichert?
Da ich nun an mehreren Rechnern über SSH arbeite, würde ich gerne alle lokalen Konfigurationen der Shell übernehmen.
Wichtige Einstellungen sind:
Meine Dotfiles sind auf GitHub im Repository „dotfiles“ veröffentlicht. Daher sind diese auch versioniert.
Das beiliegende Rakefile ist ein in Ruby geschriebenes Skript, mit dem Aufgaben erledigt werden können:
Die implementierten Aufgaben sind:
rake add[glob]
– Hinzufügen von Dotfiles zum Repository (Default: ~/.dotfiles
)ruby Beispiel-Aufrufe
rake add["~/.*[^~]"]
rake add["~/.zshrc"]
rake add["~/.aliasrc"]
rake init_vim
– Initialisiert VIM. Das Plug-in-Verwaltungs-Tool Vundle wird installiert.rake init_zsh
– Setzt die Shell auf ZSH.rake install
– Erzeugt symbolische Links im Home-Verzeichnis zu den im Repository liegenden *.symlink
-Dateien. Es
erzeugt ggf. ein Backup der vorhanden Datei. Außerdem werden alle *.erb
-Dateien generiert.rake install_bin
– Erzeugt einen symbolischen Link aller Skripte in ~/sys/bin/*
.rake list
– Listet diese Aufgaben auf.rake sync
– Synchronisiert Dotfiles vom Repository mit dem Home-Verzeichnis.rake uninstall
– Löscht alle erzeugten symbolischen Links aus dem Home-Verzeichnis. Backups werden
wiederhergestellt.rake update
– Holt sich neue Versionen des Repositories und sychronisiert diese.Der folgende Inhalt meiner Konfigurationsdateien ist nicht vollständig, daher lohnt sich ein Blick in das Repository.
Ich würde mich über einen Kommentar freuen, wenn jemand meine Konfigurationedateien nutzt oder nur einen Teil davon. Habe ich wichtige Dateien vergessen?
]]>Das Skript funktioniert nur mit dem Paketverwaltungswerkzeug pacman
, das unter Arch Linux genutzt wird.
$ wget https://raw.github.com/gist/2720970/b0cc69d2dab52217fe535fe47bc2e346cd7453e4/pacinstalled.rb
$ chmod +x pacinstalled.rb
ruby pacinstalled.rb
packages
parst alle Pakete aus der Ausgabe von pacman -Qe
. Daraus wird ein Hash mit den Schlüsseln source
, name
, version
und group
erstellt.lang_en
: In dieser Umgebung werden alle Konsolenausgaben in Englisch getätigt. Würde ich diese Umgebung nicht nutzen, würden alle anderen Sprachen, als die, die ich nutze, nicht unterstützt.info
ist eine Funktion, die ich im Moment nicht benutze, aber mit der es möglich ist mittels eines Hashs auf verschiedene Informationen eines Pakets zuzugreifen. Es sind alle Informationen, die durch pacman -Qi <paketname>
angezeigt werden.sort_hash
sortiert meinen Hash mittels des übergebenen Schlüsselarrays. Dieses Schlüsselarray beinhaltet alle Schlüssel des zu sortierenden Hashs, wobei diese sich in der gewünschten Reihenfolge befinden.Anschließend werden diese Funktionen aufgerufen und die Pakete werden nach den Paketquellen (core
, extra
, etc.) gruppiert und sortiert.
Danach werden alle Pakete ausgegeben.
Das Skript ist noch erweiterbar. Zum Beispiel könnten Optionen steuern, ob Pakete aus allen Paketquellen angezeigt
werden sollen, oder ob zum Beispiel die aus extra
nicht angezeigt werden sollen.
Wenn ich mir die nötigen Kenntnisse angeeignet habe, dann werde ich vielleicht ein Gem screiben, das pacman
unter Ruby
nutzbar macht.
Diese Library ist für JSON zuständig. Natürlich kann diese auch durch ein
$ gem install oj
installiert werden, da diese auf RubyGems gehostet ist. Wenn ich mir die Benchmarks dazu ansehe, sieht man schon einen gewaltigen Unterschied:
Summary:
System time (secs) rate (ops/sec)
------- ----------- --------------
Oj::Doc 0.094 1059995.760
Ruby 0.503 198851.434
Comparison Matrix
(performance factor, 2.0 row is means twice as fast as column)
Oj::Doc Ruby
------- ------- -------
Oj::Doc 1.00 5.33
Ruby 0.19 1.00
Hinweis: Dies ist aber nicht für einen eindeutigen Vergleich ausreichend. Weitere Benchmarks sind in der README
dargestellt.
“` ruby require ‘oj’
h = { ‘one’ => 1, ‘array’ => [ true, false ] } json = Oj.dump(h)
h2 = Oj.load(json) puts “Same? #{h == h2}”
“`
Diese weitere Bibliothek ist nicht für JSON zuständig, sondern für XML. Auch diese kann durch ein
$ gem install ox
von RubyGems installiert werden. Als Vergleich wurden verschiedene Gems hinzugezogen:
Gem | parse | to_s
Nokogiri | 3.56 seconds | 7.03 seconds
LibXML | 3.67 seconds | 0.67 seconds
Ox | 1.90 seconds | 0.33 seconds
An dem unten stehenden Beispiel kann man erkennen, dass die API einfach zu benutzen ist.
“` ruby require ‘ox’
class Sample attr_accessor :a, :b, :c
def initialize(a, b, c)
@a = a
@b = b
@c = c
end end
obj = Sample.new(1, “bee”, [‘x’, :y, 7.0])
xml = Ox.dump(obj)
obj2 = Ox.parse_obj(xml) “`
Ich hatte verschiedene Möglichkeiten ausprobiert:
Die Lösung ist eigentlich ganz einfach, man muss aber erst mal drauf kommen. Wie das immer der Fall ist. ;-)
Durch das Update auf die neue Version der GNOME-Shell musste auch die
tolle Extension gnome-shell-system-monitor-applet
aktualisiert
werden. Das passierte wunderbar, aber ich glaube, dass dadurch ein Haken gesetzt wurde.
Der Haken befindet sich unter Preferences > Battery > Hide System Icon
. Wenn dieser gesetzt ist, wird das
System-Symbol ausgeblendet.
Einfach den Haken herausnehmen und das Symbol wird wieder angezeigt.
]]>Ich habe mich an diesen Pull Request auf GitHub gehalten. Dort wurden alle nötigen Veränderungen vorgenommen. Welche Dateien hinzukamen oder verändert wurden ist im Diff dargestellt.
Damit die neu hinzu gekommenen Dateien nicht von Hand installiert werden müssen, stellt ich hier ein Skript zur Verfügung, dass das macht.
1 2 3 4 5 6 7 8 9 10 11 |
|
Beispielhafter Aufruf:
$ ./install_files_op-tags.sh ~/octopress
Damit werden die folgenden Dateien heruntergeladen und an die richtige Stelle in Octopress befördert:
Ich habe es dabei nicht belassen, sondern habe noch weitere Veränderungen durchgeführt. Zum Beispiel wollte ich, dass die Tags am Artikelende nach den Kategorien angezeigt werden. In der Archiv-Ansicht habe ich die Tags auch hinzugefügt.
Außerdem musste ich noch das Plugin related_posts.rb
anpassen, damit es funktioniert hat.
In dem nachfolgenden Diff sind alle Unterschiede erkennbar, die ich durchgeführt habe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
|
Bei Fragen oder sonstigen Anregungen, freue ich mich auf einen Kommentar oder eine E-Mail.
]]>Auf der Suche nach dem Dateiort, der viel Speicher verbraucht, fiel mir auf, dass einige Dateien unter
/var/cache/pacman/pkg
die Ursache sind. In diesem Ordner landen alle Pakete, die auf dem System installiert sind.
Es werden nicht nur die aktuellen Versionen dort abgelegt, sondern auch alle jemals installierten.
Da ich eine Distribution einsetze, die „Rolling Releases“ nutzt und daher viele Updates eingespielt werden, wird der
Ordner gerne mal mehrere Gigabyte groß.
Pacman bietet zwei Möglichkeiten, wie man diesen Cache bereinigt. Bei der Bereinung werden einfach nur Dateien gelöscht.
Achtung: Den Cache zu bereinigen mag zwar weiteren Speicherplatz hervorbringen, aber ist nur auf einem stabil laufenden System zu empfehlen. Nach dem Bereinigen sind laut Arch-Wiki keine Downgrades von Paketen mehr möglich!
Durch die folgende Eingabe werden alle Pakete entfernt, die nicht installiert sind. Alle installierten Pakete
bleiben bestehen. Unbenutzte Repositories aus /var/lib/pacman
werden entfernt:
# pacman -Sc
Eine Alternative ist den ganzen Cache zu löschen. Damit werden alle Pakete entfernt:
# pacman -Scc
Zudem gibt es noch ein in Python geschriebenes Skript CacheClean, das alte Pakete bis zu einer angegebenen Version löscht. Außerdem ist es möglich sich anzeigen zu lassen, welche Pakete durch das Programm gelöscht werden oder welche Pakete gelöscht wurden.
Mit dem nachfolgenden Befehl werden alle Versionen, bis auf die zwei neuesten, gelöscht.
$ cacheclean 2
]]>In meiner Konfiguration von VIM habe
ich einen weiteren AutoCommand hinzugefügt, der dafür sorgt, dass Skripte automatisch ausführbar gemacht werden, wenn
diese abgespeichert wurden.
Außerdem wird die Shebang automatisch einer neuen Ruby-Datei
hinzugefügt.
Die folgenden Zeilen müssen der ~/.vimrc
hinzugefügt werden.
“` vim ~/.vimrc augroup Shebang
au!
au BufNewFile *.rb 0put =\"#!/usr/bin/env ruby\<nl># encoding: utf-8\<nl>\"|$
augroup END
augroup Executable
" automatically give executable permissions if file begins with #! and contains '/bin/' in the path
au!
au BufWritePost * call MakeExecutable()
augroup END “`
“` vim ~/.vimrc ” automatically give executable permissions if file begins with #! and contains ‘/bin/’ in the path function! MakeExecutable()
if getline(1) =~ "^#!.*/bin/"
silent !chmod a+x <afile>
endif
endfunction “`
Die Zeile 3 im oberen Listing setzt die Shebang für Ruby-Skripte. In der Zeile 9 werden alle Skripte, die eine Shebang haben, nach dem Speichern ausführbar gemacht.
Ich werde noch weitere Shebangs für andere Dateiendungen hinzufügen. Gerne nehme ich Vorschläge entgegen.
Das nachträgliche chmod +x <file>
entfällt somit für meine Skripte. Klasse!
Firefox >
Lesezeichen > Alle Lesezeichen anzeigen > Importieren und Sichern > Sichern...
aufgerufen wird.
Aus allen Lesezeichen werden Anfragen an den Server gestellt. Dieser schickt in der Antwort den eingesetzten
Server-Typ mit. Alle Typen werden aufgenommen und gezählt.
Am Ende bekommt man so eine Übersicht über die eingesetzten Server der eigenen Lesezeichen.
$ gem install curb http_headers
$ wget https://raw.github.com/gist/2253541/6d60762a76d17f520b825e4cd875c31cf3767390/count_server.rb
$ chmod +x count_server.rb
$ ./count_server.rb bookmarks-2012-03-31.json
parse_json
parst die angegebene JSON-Datei zu einem JSON-Objekt.
get_server_uri_json
sucht rekursiv im JSON-Objekt nach URIs, die das HTTP-Protokoll nutzen. Es
werden nur die Domains aufgenommen. Zudem werden auch alle gleichen URIs gelöscht. Das ist
dann nötig, wenn man mehrere Links zu gleichen Domains gespeichert hat.
Beispiel: http://blog.dsiw-it.de/me/
wird zu http://blog.dsiw-it.de
fetch_uris
setzt die Anfragen an die Server der URIs ab und speichert die Antwort in einem Hash ab. Dabei
werden Weiterleitungen verfolgt.
filter_headers
filtert aus allen Antworten nur den Header heraus, sodass der Body verworfen wird. Wirklich
Speichersparsam ist das nicht, mir ist aber keine bessere Möglichkeit eingefallen.
get_server_types
filtert aus den Headern die eigentlichen Server-Bezeichnungen raus und nutzt
filter_version
.
filter_version
filtert die Versionsnummern der Bezeichnungen heraus. Ich habe festgestellt, dass diese immer nach
einem /
folgen. Also die Bezeichnungen dieses Schema haben: Serverbezeichnung/Version_und_andere_Informationen
.
add_server
fügt einen neuen Servertyp mit der Anzahl 1 hinzu, wenn dieser noch nicht im Hash
enthalten ist, ansonsten wird die Anzahl des Typs inkrementiert (+1).
reverse_sorted
sortiert die Serveranzahl absteigend, sodass der meist genutzte Server ganz oben auf der Liste
steht.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Anmerkung: Dadurch, dass ich sehr Open-Source interessiert bin, kann es die Zahlen beeinflussen. Entsprechend wird der Apache in Gegensatz zum Microsoft IIS sehr oft genutzt.
Leider brauchte das Skript für diese Anzahl an Servern lange 23 Minuten (siehe letzte Zeile).
Wie man in der Funktion fetch_uris
erkennen kann, habe ich dort ein paar Zeilen auskommentiert. Wenn diese wieder von
Ruby interpretiert werden, dann würden die Anfragen von Curb parallel verlaufen. Die Laufzeit fiel damit auf ungefähr
eine Minute. Leider wurden dabei viele leere Antworten in die Liste aufgenommen. Bei dieser Anzahl der Server waren es
700 Anfragen mit keiner Information. Mit zunehmender Anzahl der parallelen Anfragen, wuchs die Anzahl der leeren
Antworten exponentiell.
Ich habe mich an dieses Beispiel vom Gem gehalten.
Ich freue mich auf Verbesserungsvorschläge!
Wie schaut bei euch die Server-Verteilung aus?
]]>
gem install curb http_headers
wget https://raw.github.com/gist/2253504/30fc885dc04a3c815dc52e22c9368bad4d9f728f/httpheader.rb
chmod +x httpheader.rb
$ ./httpheader.rb dsiw-it.de
Ich würde mich freuen, wenn du einen Kommentar hinterlassen würdest, wenn du es nutzt.
]]>~/.rvm
. In diesem werden verschiedene Ruby-Versionen abgespeichert, sowie die
entsprechenden Gems. (Gems sind Libraries, die in Ruby geschrieben wurden.)Im folgenden beziehe ich mich nur auf die systemweite Installation. Das heißt, dass nicht Ruby mittels RVM genutzt wird.
Das stellt man sicher, indem man prüft ob in einem der übergeordneten und im selben Verzeichnis eine Datei namens
.rvmrc
enthalten ist und geladen wurde. Oder man startet eine neue Konsole im Home-Verzeichnis und beobachtet die
Meldungen. Wenn eine Meldung wie Using /home/dsiw/.rvm/gems/ruby-1.9.2-p290
ausgegeben wurde, dann wird Ruby mittels RVM genutzt.
Wenn ein Gem durch den Befehl
$ gem install <gemmodule>
installiert wird, dann landen diese im Ordner ~/.gem
. Dabei ist darauf zu achten, dass der Befehl nicht mit
Superuser-Rechten ausgeführt wird, sonst werden die Gems in einem anderen Ordner installiert.
Danach wird der Ordner ~/.gem/ruby-<version>/bin
erstellt, der alle ausführbaren Ruby-Skripte enthält.
Leider ist dieser Pfad nicht in der globalen $PATH
-Variable enthalten.
Der letzte Satz suggeriert schon, dass dieser Pfad dem PATH
hinzugefügt werden sollte. Dazu wird die folgende Zeile der
~/.zshrc
oder ~/.bashrc
hinzugefügt.
sh
[[ -d $HOME/.gem/ruby/1.9.1/bin ]] && export PATH=$PATH:$HOME/sys/bin:$HOME/.gem/ruby/1.9.1/bin
Gegebenenfalls ist zu prüfen, ob der Pfad auch der richtige ist.
Der Test mit -d
prüft, ob der Ordner vorhanden ist. Falls das der Fall ist, dann wird der Pfad der PATH
hinzugefügt.
Leider habe ich noch keine Möglichkeit gefunden, wie die statische Version aus dem Pfad entfernt werden kann. Dies ist problematisch, wenn Ruby aktualisiert wird und der neue Pfad eine andere Version enthält. Außerdem ist mir nicht klar, wieso die Version 1.9.1 im Pfad steht, obwohl die Version 1.9.3 genutzt wird.
]]>Dieser Teil beschäftigt sich mit dem Einrichten und Konfigurieren von Git. Desweiteren werden Tipps und Tricks, Software und meine Konfiguration vorgestellt. Interessante Links sind im letzten Abschnitt beigefügt.
Soweit die Theorie. Nun widmen wir uns dem Einrichten eines Repositorys, das nicht schwierig ist. Wie dies funktioniert wird nachfolgend erklärt.
Unter Arch Linux wird das Paket git
benötigt. Dieses wird durch das folgende Kommando installiert:
$ pacman -S git
Unter Ubuntu:
$ sudo apt-get install git
Nun möchten wir ein solches Repository erstellen. Dazu wählt man einen Ordner aus, in dem dieses Repo erstellt werden
soll. In meinem Fall ist das ~/tmp/git
. Nachdem in dieses Verzeichnis gewechselt wurde, gibt man einfach den Befehl
$ git init
ein und das war’s!
Es wurde ein versteckter Ordner .git
erstellt. Dort sind alle relevanten Daten enthalten, die Git benötigt.
Möchte man nun dieses Repo wieder löschen, so reicht es, wenn man diesen Ordner löscht. Gegebenfalls sollte man weitere
Konfigurationsdateien wie .gitignore
auch löschen.
Man sollte allersdings vor dem Löschen des .git
-Ordners alle Branches zu einem Branch mergen, sodass dieses
Verzeichnis auf dem aktuellen Stand ist. Würde man dies nicht tun, würden Daten in einem anderen Branch verloren
gehen!
Das Veröffentlichen von Repositories ist auf dem eigenen Server möglich, wenn dieser Git installiert hat oder man nutzt einen externen Anbieter. Ich empfehle GitHub, dort können beliebig viele Repositories erstellt werden. Dieser Dienst ist kostenlos, wenn es sich um Open-Source-Projekte handelt, andernfalls zahlt man ein paar Euro pro Monat, um private Repositories zu nutzen.
Zuzüglich zu der Kernsoftware git
kann weitere Software eingesetzt werden.
Ich nutze die ZSH mit der Erweiterung
oh-my-zsh, die das Plug-in git
zur Verfügung stellt. Dieses zeigt
im Prompt, in welchem Branch man sich gerade befindet und ob es Veränderungen gibt, die zum Index hinzugefügt werden
können.
Es gibt auch ein Git-Prompt für die Bash oder ein weiterer Bash-Prompt
lvv/git-prompt.
Das Ignorieren von Dateien wird in der Konfigurations-Datei .gitignore
festgelegt. Hierbei können einzelne Dateien
oder Ordner ignoriert werden. Zudem sind
Wildcards erlaubt.
Es gibt aber auch die Möglichkeit Dateien aus diesem Ausschluss auszuschließen, das heißt, dass diese nicht mehr von Git
ignoriert werden. Dazu setzt man ein Ausrufezeichen (!
) vor den Eintrag.
Ein Beispiel ist im Ubuntuusers-Wiki festgehalten.
Meine Konfiguration befindet sich im Home-Verzeichnis und sieht folgendermaßen aus:
bash ~/.gitconfig
[user]
name = DSIW
email = dsiw@dsiw-it.de
[color]
ui = auto
status = auto
branch = auto
interactive = auto
diff = auto
[color "branch"]
current = yellow reverse
local = yellow
remote = green
[color "diff"]
meta = yellow bold
frag = magenta bold
old = red bold
new = green bold
[color "status"]
added = yellow
changed = green
untracked = cyan
[pack]
threads = 0
[diff]
external = /usr/bin/vimdiff
[gui]
[github]
user = DSIW
token = [Hash]
[alias]
st = status
ci = commit
br = branch
co = checkout
df = diff
dc = diff --cached
lg = log -p
lol = log --graph --decorate --pretty=oneline --abbrev-commit
lola = log --graph --decorate --pretty=oneline --abbrev-commit --all
ls = ls-files
ign = ls-files -o -i --exclude-standard
unstage = reset HEAD --
last = log -1 HEAD
[core]
excludesfile = /home/dsiw/.git/git_ignore
Unter dem Abschnitt [color]
werden die Farben aktiviert und in allen unteren Abschnitten werden die Farben dafür
definiert. Interessant ist noch der Alias-Abschnitt, die das Eingeben der Befehle verkürzen.
Teil 2 beschäftigt sich mit dem Einrichten und Konfigurieren von Git. Desweiteren werden Tipps und Tricks, Software und meine Konfiguration vorgestellt. Interessante Links sind im letzten Abschnitt beigefügt.
Git ist ein verteiltes Versionsverwaltungssystem, das von Linus Torwalds 2005 ins Leben gerufen wurde. Versionsverwaltungssysteme werden hauptsächlich für Quellcode genutzt, um kollaborativ an einer Software zu arbeiten. Dabei werden die verschiedenen Zustände der Daten festgehalten. Diese Zustände können jederzeit analysiert und wiederhergestellt werden.
Git ist in verschiedene Bereiche aufgeteilt. Es ist wichig, dass man dies verstanden hat.
Stash: In diesem landen alle versteckten Veränderungen.
Workspace: Dies ist der Arbeitsbereich, indem gearbeitet wird.
Index: In diesem werden Kopien von Veränderungen gehalten, die für die nächste Version (Commit) herangezogen werden.
Local Repository: Dies enthält alle Commits und befindet sich auf einem lokalen Speichermedium.
Remote Repository: Dies enthält alle Commits und befindet sich auf einem entfernten Speichermedium, z.B. Webspace.
Ich möchte auf ein Cheatsheet hinweisen, das die Struktur von Git sehr gut darstellt und die dazu passenden Befehle.
Ich setze voraus, dass man weiß, was die folgenden Eigenschaften sind und bewirken:
Weitere Dokumentation findet man im Git ready oder in der unten stehenden Dokumentation im letzten Abschnitt „Weitere Informationen“ im Teil 2.
Ich möchte noch auf den Stash eingehen, da dieser in anderen VCS nicht vorhanden ist.
Der Stash ist eine Ablage für Änderungen, die im Moment stören. Dies wird zum Beispiel genutzt, wenn der Kunde ein Bug
sofort gefixt haben möchte, dann verstaut man die aktuellen Änderungen, an denen man gerade gearbeitet hat auf dem Stash
und kann somit den Bug fixen. Der Fix wird commitet und ggf. gepusht und danach können die verstauten Änderungen
wieder zurückgeholt werden, sodass man damit weiterarbeiten kann.
Siehe Verstaue deine Änderungen.
Jetzt wäre doch die Überlegung wert, ob man nicht das ganze Betriebssystem mit allen persönlichen Daten mit solch einem Versionsverwaltungssystem verwaltet. Das existiert auch schon und nennt sich ”GitFS” (Git Filesystem). Allerdings ist dieses noch in einem Beta-Status.
Eine weitere Möglichkeit besteht darin, dass man auch Backups mit dem VCS machen kann. Dafür wurde das Programm bup geschrieben. Es befindet sich aber auch wie das vorherige GitFS in einem sehr frühen Entwicklungsstadium, sodass man es mit Vorsicht nutzen sollte. Einer der Entwickler hielt während dem 28C3 im letzten Jahr einen Vortrag darüber, der auch aufgezeichnet wurde: Video in besserer Qualität | Youtube
Verteilte Versionsverwaltungssysteme (VCS) sind, im Gegensatz zu zentralen Versionsverwaltungssystemen, verteilt. Das
heißt, dass es ein einziges, zentrales Repository gibt, das von allen Teilnehmern genutzt wird. Das heißt aber auch,
dass immer eine Verbindung zu diesem Repository bestehen muss, wenn man Commiten möchte.
Konnektivitätsschwankungen in Verbindung mit zentralen VCS führt kurz- oder langfristig zu unsauberen Repositories.
Ich fahre zum Beispiel auf einer Zugfahrt durch Deutschland und arbeite an einer Software. Ich setze ein zentrales VCS
ein und es gibt immer wieder Verbindungsabbrüche. Da es zu lange dauern würde immer wieder auf Verbindungen zu warten,
arbeite ich einfach weiter und commite erst dann, wenn ich eine Verbindung habe. Das führt zu unsauberen Commits.
Normalerweise werden Commits in Einheiten zusammen gepackt, die eine Veränderung betragen. Zum Beispiel das
Hinzufügen eines Features oder das Fixen eines Bugs. Bei meiner Zugfahrt würden die Commit aber mehrere
Veränderungsblöcke zusammenfassen. Somit ist die Versionsgeschichte sehr unsauber und man kann nicht ohne
Mehraufwand einen älteren Commit auschecken.
Dieser Nachteil besteht bei verteilten oder dezentalisierten Versionsverwaötungssystemen nicht. Jeder Teilnehmer hat
ein eigenes lokales Repository zusätzlich zum zentralen Repository. Damit kann ich, auch bei Verbindungsschwankungen,
saubere Commits auf meinem lokalen Repository durchführen. Irgendwann können diese Commits dem zentralen Repository
mit einem Push zugeführt werden.
Ein weiterer Vorteil davon ist, dass alle Teilnehmer völlig unabhängig von den anderen Teilnehmern arbeiten können. Es
können sogar mehrere Teilnehmer gleichzeitig an einer Datei arbeiten, da diese nur auf den lokalen Kopien Veränderungen
durchführen. Es gibt VCS, die das nicht zulassen: SVN.
<leader>iuw
: Einfügen des Links um das unter dem Cursor stehenden Wort.<leader>iuW
: Einfügen des Links um das unter dem Cursor stehenden WORD (Wort mit Sonderzeichen).<leader>iu
: Einfügen des Links um den marktierten Text.Der Link muss sich in der Zwischenablage befinden.
Die unten stehenden Markos fügen Links, die sich in der Zwischenablage befinden, an dieser Stelle so ein, dass ein Link entsteht.
Ich habe deswegen iu
als Kommando genutzt, da Links eingefügt werden: “insert url”. Natürlich können diese an eure
Vorlieben angepasst werden.
tex Makros
au Filetype markdown,octopress nmap <leader>iuw i[xepa("+P
au Filetype markdown,octopress nmap <leader>iuW i[xEpa("+P
au Filetype markdown,octopress vmap <leader>iu s[lxhf]hxa("+Pl
Hinweise: Ich nutze das Plug-in surround.vim, siehe
meinen Artikel über Plugins. Wenn dieses Plug-in nicht genutzt wird, muss das
Makro angepasst werden.
Üblicherweise ist es die Leader-Taste \
. In meinem Fall habe diese aber durch ,
ersetzt. Wie ich das gemacht habe,
kann man in meiner VIM-Konfiguration in Zeile 403 erkennen: let mapleader=","
.
Am Ende erkennt man die Sequenz "+p
. Dies fügt den Inhalt des Registers +
bzw. der Zwischenablage an dieser Stelle
ein. Weitere Register und Mappings bzgl. der Zwischenablage habe ich in diesem Artikel
erklärt.
Ich habe meine Schritte, nachdem ich qq
gedrückt habe, ins Register q
aufgezeichnet. Das Aufzeichnen wird durch das weitere Mal Drücken von q
beendet. Den Inhalt des Registers habe ich dann in meine ~/.vimrc
mit "qp
eingefügt.
Viel Spaß damit!
]]>Zum einen wird nun die Zeit am Anfang des Prompts angezeigt.
Zum anderen wird ein ERR:#
auf der rechten Seite dargestellt, wenn das vorherige Programm mit einem Fehler beendet
wurde. Genauer: es wird der return code
des Programms angezeigt, wenn dieser ungleich 0 war.
In dem unten stehenden Beispiel erkennt man gut, dass der Befehl git asd
mit einem Fehler abbrach und der
entsprechende return code
angezeigt wurde.
Ein Pull Request ist die Möglichkeit von GitHub.com um Veränderungen an andere Repositories mitzuteilen. Eigentlich ist es nur eine Merge-Anfrage. Dazu habe ich mir das Oh-My-ZSH-Repository geklont, die Veränderung commitet und gepusht. Anschließend habe ich den Pull Request abgesetzt.
Die Veränderungen halten sich in Grenzen:
Ich habe deshalb dieses Bild eingefügt, da es keine schöne Möglichkeit gibt ein Diff als Text hier einzufügen, sodass
das schön aussieht.
Dieses Bild wurde aus vimdiff
(Theme: Solarized) mit
Shutter gemacht.
source/_posts
befinden, nicht mit der Dateiendung md
oder markdown
nutze möchte, habe ich diese in octopress
umbenannt. Um dies umzusetzen müssen an zwei Schrauben gedreht werden,
damit Jekyll bzw. Octopress sauber funktioniert und der Inhalt der Dateien als Markdown interpretiert wird.
Die bestehenden *.post
-Dateien müssen umbenannt werden:
$ cd source/_posts
$ for i in *.markdown; do mv $i "${i%.markdown}.octopress"; done
Im Rakefile habe ich folgenden Variablen einen neuen Wert zugewiesen.
new_post_ext = "octopress" # default new post file extension when using the new_post task
new_page_ext = "octopress" # default new page file extension when using the new_page task
Update vom 2012-03-31: Desweiteren muss eine weitere Jekyll-Option hinzugefügt werden.
yaml
markdown_ext: 'markdown,mkd,mkdn,md,octopress'
Somit entfällt der Abschnitt “Library”.
Das reicht leider noch nicht. Jekyll muss wissen, dass die Dateien mit der Endung octopress
auch in Markdown
geschrieben werden und somit der entsprechende Konverter genutzt wird.
Dazu habe ich die Datei ~/.rvm/gems/ruby-1.9.2-p290/gems/jekyll-0.11.0/lib/jekyll.rb
angepasst. Natürlich muss der
Pfad eurem System angepasst werden.
In der Zeile 69 steht folgendes:
[...]
'markdown_ext' => 'markdown,mkd,mkdn,md',
[...]
Ich habe nun diesem Schlüssel einen weiteren Wert octopress
hinzugefügt:
[...]
'markdown_ext' => 'markdown,mkd,mkdn,md,octopress',
[...]
Leider habe ich noch keine Möglichkeit gefunden, dass dieser Wert zum Bespiel in der Mit dem Update vom 2012-03-31 hat sich das erledigt._config.yml
gesetzt
wird.
zsh
dazu beiträgt, aber
seien wir doch mal ehrlich. Auf Dauer ist es recht zeitaufwändig.Seit kurzem nutze ich dafür einen Dateimanager, mit dem viel Zeit gespart werden kann. Ich hatte mir vorher schon ein paar Dateimanager für die Konsole angesehen. Zum Beispiel habe ich mal den Midnight Commanger ausprobiert, aber nach einem kurzen Testen hat er mir nicht gefallen.
Außerdem gibt es noch Dateimanager, die die Tastenkombinationen von vim
nutzen, sodass ich nicht viel umlernen muss
und viel Funktionalität vorhanden ist.
Unter diesen Dateimanagern habe ich zwei entdeckt. Der eine nennt sich Ranger, der andere
VIFM. Ranger gefiel mir nicht sonderlich, da ich schon eine zweigeteilte
Sicht haben wollte. Das Löschen von Dateien hatte auch nicht sehr gut funktioniert. Die Tastenkombination dd
sollte
dies tun – tat es aber nicht.
In VIFM ist das schon besser. Es hat eine zweigeteilte Sicht und die normalen Tastenkombinationen fuktionieren
intuitiv richtig. Ein paar von diesen sind nachfolgend dargestellt:
k moves up.
j moves down.
h moves up one directory.
l moves into a directory or launches a file.
gg move to the top of the file list.
G move to the bottom of the file list.
H move to the first file in the window.
M move to the file in the middle of the window.
L move to the last file in the window.
e explore file in the current pane.
i opens file with associated program even if it's an executable.
cw rename a file or files.
cW change only name of file (without extension).
cl change link target.
yy yanks the selected files.
dd moves the selected files to the trash directory.
DD removes the selected files.
p will copy the yanked files to the current directory or move the files to the current
directory if they were deleted with dd or :d[elete] or if the files were yanked from
the Trash directory.
u undo last change.
Ctrl-R redo last change.
v enter visual mode.
V enter visual mode.
C clone file [count] times.
Damit nach dem Öffnen von Dateien automatisch das richtige Programm gestartet wird, habe ich meine Konfiguration um ein paar Zeilen erweitert:
“` text Auszug aus ~/.vifm/vifmrc ” FuseZipMount filetype .zip,.jar,.war,.ear FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR
” Documents filetype .pdf,.djvu,*.ps evince
” Media filetype .avi,.mov,.mkv,.wmv,.mp4 vlc filetype .mp3 mpg123 filetype .jpg,.jpeg,.gif,.png,.bmp,.tiff eog
” ISOs filetype *.iso mountiso “`
Dieser Filemanager hat verschiedene nützliche Funktionen, die nachfolgend vorgestellt werden.
Durch die Befehle :map
, :noremap
, :unmap
lassen sich eigene Tastenkombinationen erstellen und löschen.
Das Suchen geschieht mit dem Zeichen /
, wie es in VIM auch der Fall ist. Der nächste passende Treffer wird mit n
und der vorherige mit N
gefunden.
In der Default-Ansicht werden keine versteckten Dateien (Dot-Files) angezeigt. Nachdem man za
eingegeben hat, werden
auch diese angezeigt, sodass das Navigieren darin möglich ist.
Durch den Befehl :filter /regex/
werden alle Dateien nach dem entsprechenden
Regulären Ausdruck (Regex) gefiltert. Zum Beispiel habe ich einen
Ordner, in dem einige Videos vom 28C3 enthalten sind. Diese würde ich gerne nach
deutschen Videos filtern. Der Inhalt des Verzeichnisses sieht entsprechend aus:
[...]
28c3-4800-en-how_governments_have_tried_to_block_tor_h264.mp4
28c3-4802-en-towards_a_single_secure_european_cyberspace_h264.mp4
28c3-4804-de-politik_hacken_h264.mp4
28c3-4811-en-rootkits_in_your_web_application_h264.mp4.part
28c3-4813-en-macro_dragnets_h264.mp4
28c3-4814-en-behind_the_scenes_of_a_c64_demo_h264.mp4
28c3-4816-en-7_years_400_podcasts_and_lots_of_frequent_flyer_miles_h264.mp4
28c3-4818-en-evolving_custom_communication_protocols_h264.mp4
28c3-4821-en-not_your_grandfathers_moon_landing_h264.mp4
28c3-4826-en-a_brief_history_of_plutocracy_h264.mp4
28c3-4828-de-antiforensik_h264.mp4
28c3-4832-de-neue_leichtigkeit_h264.mp4
28c3-4844-de-eu_datenschutz_internet_der_dinge_h264.mp4
28c3-4847-en-reverse_engineering_usb_devices_h264.mp4
28c3-4848-en-the_coming_war_on_general_computation_h264.mp4
28c3-4856-en-the_engineering_part_of_social_engineering_h264.mp4
28c3-4866-de-fnord_jahresrueckblick_h264.mp4
[...]
Mit den beiden folgenden Befehlen werden nur deutsche Videos angezeigt:
:filter /28c3-.{4}-de.*/
:invert
oder abgekürzt mit
:filter! /28c3-.{4}-de.*/
Ich hatte auch /28c3-\d{4}-de.*/
ausprobiert, aber leider wurde \d
nicht als Zahl erkannt.
Die Ausgabe ist danach:
[...]
28c3-4804-de-politik_hacken_h264.mp4
28c3-4828-de-antiforensik_h264.mp4
28c3-4832-de-neue_leichtigkeit_h264.mp4
28c3-4844-de-eu_datenschutz_internet_der_dinge_h264.mp4
28c3-4866-de-fnord_jahresrueckblick_h264.mp4
[...]
Ich habe mir ein paar Markierungen gesetzt, um schnell zu diesen Ordnern zu gelangen. Das folgende steht in meiner Konfiguration:
text Auszug aus ~/.vifm/vifmrc
mark h /home/dsiw ../
mark b /home/dsiw/.blog source/
mark d /home/dsiw/downloads ../
Es können Markierungen aber auch dynamisch während der Laufzeit von VIFM gesetzt werden, indem man ein m
vor
einen Buchstaben setzt. Zum Beispiel wird mG
eine Markierung gesetzt. So lässt sich die aktuelle Position des Fensters
mit 'G
wieder aufrufen.
:view
wird der Inhalt der aktuellen Datei im rechten Fenster dargestellt.:sync
bewirkt, dass der eigene Standort im anderen Fenster aufgerufen wird.:sh[ell]
, um eine Shell in diesem Ordner
zu öffnen.:!
stehen: also
um Bepsiel :!ls -lah
.man vifm
Kennt ihr noch weitere oder sogar bessere Dateimanager, die auf der Konsole genutzt werden können? Welche nutzt ihr?
]]>