Skip to main content

Programm- oder Funktionsrückgabe auswerten

In Bash-Scripten werden oft externe Programme und Tests ausgeführt deren Rückgabewerte man kontrollieren möchte, z.B. ob das Programm gelaufen ist oder ob es einen Fehler gab.

Folgendes wird gerne verwendet, ist aber für einen einfachen Test etwas umständlich:

# Beispiel: gibts einen bestimmten Benutzer?
grep -q username /etc/passwd
if (($? > 0)); then
  echo 'Benutzer wurde nicht gefunden' >&2
  exit 1
fi

Schneller und besser zu lesen ist dieser Code:

if grep -q username /etc/passwd; then
  # nix machen
  :
else
  echo 'Benutzer wurde nicht gefunden' >&2
  exit 1
fi

# oder noch kürzer mit Negation
if grep -q username /etc/passwd; then
  echo 'Benutzer wurde nicht gefunden' >&2
  exit 1
fi

Alternativ gehts auch mit einer || (ODER, wenn der Rückgabewert nicht 0 ist) oder && (UND, wenn der Aufruf eine 0 zurückgibt) Verknüpfung:

grep -q username /etc/passwd || {
  echo 'Benutzer wurde nicht gefunden' >&2
  exit 1
}

Die Auswertung von $? ist damit eigentlich nur notwendig, wenn man tatsächlich auf einen ganz bestimmten Rückgabewert prüfen will. rsync etwa liefert für viele Fehler einen bestimmten Code:

    0 Success
    1 Syntax or usage error
    2 Protocol incompatibility
    3 Errors selecting input/output files, dirs
    4 Requested action not supported: an attempt was made to manipulate 64-bit files on a platform that cannot support them; or an option was specified that is supported by the client and not by the server.
    5 Error starting client-server protocol
    6 Daemon unable to append to log-file
    10 Error in socket I/O
    11 Error in file I/O
    12 Error in rsync protocol data stream
    13 Errors with program diagnostics
    14 Error in IPC code
    20 Received SIGUSR1 or SIGINT
    21 Some error returned by waitpid()
    22 Error allocating core memory buffers
    23 Partial transfer due to error
    24 Partial transfer due to vanished source files
    25 The –max-delete limit stopped deletions
    30 Timeout in data send/receive
    35 Timeout waiting for daemon connection

    So kann z.B. nur der Fehler in ein Logfile geschrieben werden:

    rsync -a --delete quelle ziel
    if (($? == 30)); then
        echo "Timeout in data send/receive" >> $logfile
        exit 1
    fi