cat hunting the bash Immer wieder bin ich angenehm überrascht wie viele Aufgaben ich mit BASH in oft einer (langen) oder nur wenigen Zeilen lösen kann. Warum schreibe ich dann fast alles in Skriptsprachen wie Ruby, Python oder Perl?
Ganz einfach weil die Syntax einfacher zu merken ist und BASH doch einige Eigenheiten hat, die es zu merken gilt.

Darum hier ein Versuch sämtliche gern gemachte Fehler niederzuschreiben. Ich würde mich über Kommentare eurer Fallgruben von euch freuen.

  1. whitespaces und wildcards
    mv $file_old $file_new # falsch
    

    Das kann bei Dateinamen mit Leerzeichen oder wildcards zu Problemen führen, wenn man sich nicht sicher ist welchen Inhalt eine Variable hat, sollte man sie in Anführungszeichen setzen.

    mv "$file_old" "$file_new"
    

    Nun können in $file_old und $file_new Leerzeichen und wildcards wie * oder ? oder [...] verwendet werden.

  2. runde Klammern werden nicht erkannt

    Ich bin schon öfter über Posting gestolpert wo das Skript mit dieser Meldung abstürzte:

    Syntax error: "(" unexpected

    Das liegt dann meistens daran das keine BASH sondern eine abgemagerte Shell wie dash verwendet wurde.
    Welche Shell verwendet wird kann über $SHELL abgefragt werden:

    echo $SHELL
  3. Variablen-Deklaration
    $ubuntu="super" # falsch
    ubuntu = "super" # falsch
    ubuntu ="super" # falsch
    

    in BASH werden einer Variable, ohne $ und ohne Zwischenabstände Werte zugewiesen.

    ubuntu="super"
    
  4. lesen und schreiben in die selbe Datei

    Es ist nicht möglich in die selbe Datei, über eine pipe zu schreiben, von der gelesen wird. In den meisten Fällen bleibt dann eine 0 Byte große Datei über.

    cat datei | sed s/foo/bar/ > datei # falsch

    Eine Lösung wäre mit einer temporären Datei zuarbeiten und diese mit der Originaldatei zu überschreiben

    sed 's/foo/bar/g' datei > tmpdatei && mv tmpdatei datei
  5. Globing verwenden

    Ein gern gemachter Fehler ist das verwenden von subshells in loops

    for x in `ls *.jpg`; do # falsch
    

    Hat einer der Dateinamen whitespaces wird es hier zu Fehlern kommen (siehe 1). Außerdem wird ein externes Kommando ls unnötig aufgerufen.
    In BASH sollte darum für solche Aufgaben das BASH interne Glob verwendet werden.

    for i in *.jpg; do
    
  6. Verwenden absoluter Pfade bei externen Programmen

    Oft werden externe Programme in BASH ohne absoluten Pfad aufgerufen, sehr sicher ist das allerdings nicht.

    dateien=`ls /home/userin/`

    Das Problem hier könnte sein das jemand mutwillig ein Programm mit den Namen ls erzeugt und nicht mehr /bin/ls wie gedacht, sondern ein manipuliertes ls ausgeführt wird.
    Ein besserer Ansatz mit einem absoluten Pfad:

    ls="/bin/ls"
    dateien=`$ls /home/userin/`