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