Nützliche bash Befehle
Script bei Fehlern abbrechen
#!/bin/bash ## Script bei Fehlern abbrechen set -e # ...Script... exit 0
Auszug aus der help-Seite von set:
host:/root# help set set: set [--abefhkmnptuvxBCHP] [-o option] [arg ...] [...] -e Exit immediately if a command exits with a non-zero status. [...]
Ein Beispiel, um das ganze zu verdeutlichen:
#!/bin/bash set -e cd / tar cvzf /backup/komplett_backup.tgz . ## Backup auf Storage-System verschieben ## # wenn das Verzeichnis /backup nicht bestehen würde, würde das Script weiterlaufen... cd /backup # ...und da wir uns noch in / befinden, würde mit dem rm-Befehl das komplette System gelöscht werden. -x verhindert dies aber! rm -r * exit 0
Script debuggen
#!/bin/bash ## Gib auf STDOUT aus, was gemacht wird set -x # ...Script... exit 0
Auszug aus der help-Seite von set:
host:/root# help set set: set [--abefhkmnptuvxBCHP] [-o option] [arg ...] [...] -x Print commands and their arguments as they are executed. [...]
-x gibt sämtliche Operationen des Scripts aus: Variablen-Zuweisungen, Schleifen, … Ein Beispiel, um das ganze zu verdeutlichen:
#!/bin/bash set -x for zahl in `seq 1 5` ; do echo "Variable \$zaehler ist nun "$zahl zaehler=$zahl done ### # Ausgabe auf der Shell: ### ++ seq 1 5 + for zahl in '`seq 1 5`' + echo 'Variable $zaehler ist nun 1' Variable $zaehler ist nun 1 + zaehler=1 + for zahl in '`seq 1 5`' + echo 'Variable $zaehler ist nun 2' Variable $zaehler ist nun 2 + zaehler=2 + for zahl in '`seq 1 5`' + echo 'Variable $zaehler ist nun 3' Variable $zaehler ist nun 3 + zaehler=3 + for zahl in '`seq 1 5`' + echo 'Variable $zaehler ist nun 4' Variable $zaehler ist nun 4 + zaehler=4 + for zahl in '`seq 1 5`' + echo 'Variable $zaehler ist nun 5' Variable $zaehler ist nun 5 + zaehler=5
Weitere coole Debugging-Optionen
Folgende set-Parameter sind meines Erachtens ganz hilfreich beim debuggen von Scripten:
# Kommandos im Script werden nur angezeigt und NICHT ausgeführt set -nv # Kommandos im Script werden angezeigt und ausgeführt set -v # Beim Zugriff auf undefinierte Variablen in Scripten wird ein Fehler gemeldet, das Script wird beendet set -u
Bash Parameterübergabe
Die Variablen $* und $@ beinhalten zwar beide die kompletten Parameter, die einem Script übergeben werden, jedoch verhalten Sie sich in Schleifen unterschiedlich. Während bei $* alle Parameter als ein Parameter behandelt werden, wird bei $@ alles als eigener Parameter verwertet, was mit einem Leerzeichen getrennt ist:
root@kiste:~$ cat parameter-test #!/bin/bash echo 'Ausgabe mit $*:' for i in "$*" ; do echo $i done echo echo 'Ausgabe mit $@:' for i in "$@" ; do echo $i done root@kiste:~$ ./parameter-test 1 2 3 4 Ausgabe mit $*: 1 2 3 4 Ausgabe mit $@: 1 2 3 4
Variablen
# Wenn die Variable leer sein sollte, wird sie mit einem neuen Wert gesetzt echo ${variable:=NeuerWert} # Ist die Variable leer, wird temporär der angegebene Wert verwendet, die Variable wird aber nicht neu gesetzt, sprich bleibt leer echo ${variable:-TemporärerWert} # Gibt eine Fehlermeldung aus, wenn die Variable nicht gesetzt/leer ist echo ${variable:?Fehlermeldung} # Zeige ab (inklusive) der n-ten Stelle in der Variable m Zeichen (Achtung: n ist zerobased) echo ${variable:2:5} # Entferne Suchmuster aus Variable, es wird das erste Muster gesucht, danach ist Schluss echo ${variable#Suchmuster} # Entferne Suchmuster aus Variable, das Muster wird im kompletten String gesucht echo ${variable##Suchmuster} # Zeichen ersetzen während der Ausgabe (nur temporär) echo ${variable//suche/ersetze}
Festplattenbelegung mit Balkengrafik
Added by Gecko / 11/11/2010
#!/bin/bash while read part size ; do echo -ne ${part}"\t"${size}"\t" size=$((${size%\%}/2)) for dash_count in `seq 1 $size` ; do echo -n '#' done for minus_count in `seq 1 $((50-size))` ; do echo -n '-' done echo done < <(df | egrep "^/" | awk {'print $6" "$5'})
Daten aus Datei mit fest belegten Spalten in Variablen schreiben
Muss man z.B. eine Datei auslesen, die mehrere Spalten hat die alle mit einem bestimmten Trenner voneinder getrennt sind, um die Daten später in Variablen zu schreiben und zu verarbeiten, kann man ja prinzipiell zeilenweise eine Datei auswerten und mit cut oder awk auf die einzelnen Felder/Spalten zugreifen. Leichter geht das mit der Umgebungsvariablen $IFS und einer while-Schleife. Hier als Beispiel die Verabreitung der /etc/passwd:
#!/bin/bash # $IFS definiert den Spaltentrenner IFS=':' while read user pass uid gid gecos home shell ; do echo ${user}" = "${shell} done < <(cat /etc/passwd)
einfaches grafisches Menu mit Weiterverarbeitung der Auswahl
result=$(dialog --clear --title "M O O" --menu "Was moechtest du?" 12 40 4 "P" "Pause" "W" "Weitermachen" 2>&1 1>/dev/tty) echo $result
Dateien verschieben
Dateien zu verschieben ist ja wohl das leichteste überhaupt:
root@kiste:~$ mv datei datei.old
Die Bash Substitution kann das aber noch ne Ecke geile:
root@kiste:~$ mv datei{,.old}
Was in den geschweiften Klammern ({}) steht, ist eine Liste, die in der genau der oben genannten Reihenfolge aufgerufen wird. Delimiter der Lsite ist das Komma (,). Würde man die Liste mit echo aufrufen, würde das so aussehen:
root@kiste:~$ echo datei{,.old} datei datei.old
Wird das echo durch mv ersetzt, würde der ausgeführte Befehl so aussehen:
root@kiste:~$ mv datei datei.old
Das Ganze geht natürlich auch mit komplett unterschiedlichen Dateinamen:
root@kiste:~$ mv /var/log/{Original,Verschoben}
Tastenkombinationen selbst zuweisen
Die Zuweisung von Tastenkombinationen erfolgt entweder global für das System über /etc/inputrc, oder für einzelne User in ~/.inputrc. So kann man sich z.B. beim drücken von <CTRL>+E den aktuellen Monat im Kalender ausgeben. Dazu ist in die Steuerdatei folgendes einzutragen:
Control-e: "cal\C-m"
Anschließend muss man sich entweder abmelden und wieder neu anmelden, um die Änderung zu laden, oder mit dem folgenden Befehl…
# für den einzelnen User bind -f ~/.inputrc # für das komplette System bind -f /etc/inputrc
<CTRL>+E zeigt dann folgendes…
November 2010 Su Mo Tu We Th Fr Sa 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