Inhaltsverzeichnis
Dies ist eine kurze Referenz kleiner (b)ash-Wissensfetzen.
Falls irgendwas nur mit der bash, aber nicht mit der ash laufen sollte, dann sollte dies explizit gekennzeichnet werden!
Allgemeines
Eingaben/Ausgaben
- >DATEI
- Standard-Ausgabe (1) in DATEI schreiben
- 1>DATEI
- dito
- >>DATEI
- Standard-Ausgabe (1) an DATEI anhängen
- 2>DATEI
- Fehler-Ausgabe (2) in DATEI schreiben
- 1>&2
- Standard-Ausgabe (1) zur Fehler-Ausgabe (2) umleiten
- 2>&1
- Fehler-Ausgabe (2) zur Standard-Ausgabe (1) umleiten
- &>DATEI
- Standard- und Fehlerausgabe in Datei schreiben
- <DATEI
- Standard-Input aus DATEI lesen
- N<DATEI
DATEI mit dem Datei-Deskriptor Nummer N als nur-lese verknüpfen
- N>DATEI
DATEI mit dem Datei-Deskriptor Nummer N als nur-schreiben verknüpfen
- N<>DATEI
DATEI fuer schreib/lese-Zugriffe als Nummer N öffnen
- N<< TRENNER
der folgende Text bis zum Auftreten einer Zeile, in der nur TRENNER steht, wird als Eingabestrom verwendet
echo <<TEXTENDE eine Zeile noch eine TEXTENDE
- N<<- TRENNER
- dito - führende Tabulatoren werden jedoch ignoriert
als DATEI kann auch immer &N (mit N als Zahl) verwendet werden, um eine Kopie des entsprechenden Datei-Deskriptors zu verwenden (also 2>&1 lenkt die Fehlerausgabe auf die Standard-Ausgabe um)
&- als DATEI schließt den angegebenen Strom
Befehls-Verkettungen
- ||
ODER - führt das folgende Kommando nur aus, wenn das erste nicht mit Fehlercode 0 beendet wurde
- &&
- UND - nur, falls das erste Kommando erfolgreich war
- die Kommandos werden nacheinander ausgeführt
- &
- das Programm wird im Hintergrund ausgeführt
- { BEFEHLE; }
- führt die Befehle in der aktuellen Shell aus (Vorsicht - falls durch eine UND-/ODER-Verknüpfung die schließende Klammer übersprungen wird, führt das zu irritierenden Fehlermeldungen)
- (BEFEHLE)
- führt die Befehle in einer neuen Shell aus (also werden keine Variablen der aktuellen Shell verändert usw.)
Anführungsstriche
- doppelte
- Variablen und rückwärtige Anführungsstriche (Backticks) werden aufgelöst
- einfache
- beides wird nicht aufgeloest
- rückwärtige
- der Text wird als Kommando interpretiert und liefert dessen Ausgabe zurück
Strukturen
- while- und for-Schleifen können durch "break" beendet und durch "continue" mit der nächsten Iteration fortgesetzt werden
- BEDINGUNG ist üblicherweise ein Programm, dessen Exit-Code verwendet wird
falls dazu das builtin "test" verwendet wird, ist auch die verkürzte Schreibweise: "[ TEST_PARAMETER ]" möglich (die Leerzeichen zwischen den eckigen Klammern sind wichtig!)
- BEDINGUNG kann auch eine beliebig lange Liste von Kommandos sein - relevant ist nur der Exit-Code des letzten Befehls
- anstelle der Zeilenumbr+che kannst du natürlich auch ein Semikolon verwenden
while
{{{while BEDINGUNG
- do BEFEHL
- BEFEHL
- done}}}
BEDINGUNG ist dabei irgendein Programm, das entweder den Exit-Code 0 (=wahr) oder eine einen beliebigen anderen Exit-Code (=falsch) zurückliefert - häufig ist dies das Programm test
until
siehe "while" - einfach "until" stattdessen einsetzen
for
{{{for VAR in LISTE
- do BEFEHL
- BEFEHL
- done}}}
- VAR ist der Name (ohne "$") der Variablen, die das aktuelle Element aus LISTE enthaelt
- dabei solltest du LISTE nicht in Anfuehrungsstriche setzen, damit die einzelnen Parameter nicht als Ganzes interpretiert werden
if
{{{if BEDINGUNG
- then BEFEHL
- BEFEHL
- BEFEHL
- fi}}}
case
{{{case $VARIABLE in
- a|b )
- BEFEHL BEFEHL ;;
- BEFEHL ;;
- )
- BEFEHL ;;
- esac}}}
String-Funktionen (Variablen-Substitution)
in Abhängigkeit vom Status der Variablen
- ${var}
- die Variable
- ${var:-default}
- falls die Variable nicht gesetzt ist, wird der default-Wert zurückgegeben
- ${var:=default}
- falls die Variable nicht gesetzt ist, wird ihr der default-Wert zugewiesen
${var:?[meldung]}: falls die Variable nicht gesetzt ist, wird meldung (oder ein Standard-Text) an Standard-Error ausgegeben und das Skript mit Fehlercode beendet - ansonsten wird der Variablenwert zurückgegeben
- ${var:+alternative}
falls die Variable gesetzt ist, wird alternative zurückgegeben, ansonsten der Wert der Variable (also null (leer))
Anmerkung zu den vorherigen Beschreibungen:
- "nicht gesetzt" bedeutet eigentlich "nicht gesetzt oder null"
- falls wirklich nur "nicht gesetzt" gemeint ist, dann muss der Doppelpunkt weggelassen werden
zeichenorientiert
- ${#var}
die Anzahl der Zeichen in var
- ${var:offset}
einen Teilstring von var, beginnend beim Zeichen Nr. offset
- ${var:offset:length}
liefert length Zeichen von var beginnend bei Zeichen Nr. offset
Ersetzungen
- ${var%regexp}
entfernt das kleinstmögliche Suffix, für das regexp zutrifft (aus var=gurgelFressFisch und regexp=F.*$ wird somit gurgelFress
- ${var%%regexp}
- entfernt das größtmögliche Suffix, fuer das "regexp" zutrifft (das obige Beispiel ergibt dann "gurgel")
- ${var#regexp}
- entfernt das kleinstmögliche Präfix
- ${var##regexp}
- entfernt das größtmögliche Präfix
* Erklärung: entfernt bedeutete in den vorangegangenen Beispielen nicht, dass die Variable verändert wird, sondern, dass dieser Teil des Strings nicht zurückgeliefert wird
gebräuchliche Beispiele
- ${DATEINAME%.pdf}
liefert den Inhalt von DATEINAME ohne die Endung .pdf (nur zur Perfektion: da ein Punkt in einem regulären Ausdruck als beliebiges Zeichen interpretiert wird, würde beispielsweise auch die Endung zpdf entfernt werden - korrekt wäre also: ${DATEINAME%\.pdf})
Berechnungen
mit $((formel)) koennen einfache arithmetische Operationen ausgefuehrt werden
- alle Variablen in der Berechnung müssen mit dem ueblichen Dollarzeichen markiert werden (fuer ash erforderlich - fuer bash nicht)
Vorsicht: i=$(($i+1)) und i=$((i+1)) ist fuer die bash nicht dasselbe - ersteres wird als unendliche Rekursion abgelehnt und letzteres liefert das erwartete Resultat (bei der ash funktioniert nur die erste Variante)
Update: dies gilt anscheinend nur bis Bash v3.x - ab v4.0 funktioniert auch i=$(($i+1))
wichtige Shell-Variablen
- $1 .. $9
- die Parameter beim Skript-Aufruf (koennen mit "shift" weitergeschoben werden, um an die folgenden Parameter zu gelangen)
- $0
- der Name des Shell-Skripts
- $*
- alle Parameter der Shell
- $@
- so aehnlich, wie "$*"
- $#
- die Anzahl der Parameter
- $?
- Exit-Code der letzten Pipeline bzw. des letzten (Vordergrund-)Kommandos
- $!
- Exit-Code der letzten Pipeline bzw. des letzten (Hintergrund-)Kommandos
- $$
die pid (Prozessnummer) des Skripts
wichtige builtins
- . DATEI
- liest DATEI ein und führt deren Zeilen in der aktuellen Shell aus (wichtig, um die Variablen der aktuellen Shell beeinflussen zu können)
- eval STRING
- wertet STRING aus und führt die resultierende Zeichenkette aus
- read [-p TEXT] VAR
gibt eventuell TEXT aus und wartet auf eine Eingabezeile von Standard-Input - diese wird VAR zugewiesen (es können auch mehrere Variablennamen angegeben werden - diese enthalten dann die einzelnen (durch Leerzeichen oder Tabulatoren getrennten) Teile der Eingabe; in der letzten Variablen steht immer der verbleibende Rest der Eingabe) - der Eingabestrom kommt oft aus einer Datei: read liefert dann einen Fehlercode zurück, wenn das Dateiende erreicht wird
- set
- Shell-Optionen setzen
- -x
- jede Skript-Zeile (nach Variablenexpansion usw.) ausgeben, bevor sie ausgeführt wird
- -u
- falls eine verwendete Variable nicht gesetzt ist, dann beende das Skript mit Fehler (schützt vor Tipp-Fehlern)
- -e
Skript sofort abbrechen, falls ein Kommando mit Fehler beendet wurde (gilt nicht fuer test, if, ||-Verkettungen usw.)
- shift [n]
rückt die aktuellen Parameter ($1 usw.) um n weiter
- test
- RTFM
- trap AKTION SIGNALE
führt AKTION (in einfachen Anführungsstrichen) aus, wenn das Programm eins der angegebenen Signale empfängt; die Signale können als Zahlen oder per Name angesprochen werden; "0" bedeutet Skript-Ende
- exit [X]
beendet das Skript und gibt den Exit-Code X (bzw. 0) zurück
Funktionen
name () BEFEHL
oder
name () { BEFEHL BEFEHL }
return X liefert den Exit-Code X zurück
- die Parameter der Funktion sind als "$1" bis "$9" verfuegbar
- der Aufruf einer Funktion startet einen eigenen Prozess
Variablen, die nur innerhalb der Funktion gültig sein sollen, müssen bei der ersten Verwendung durch ein vorangestelltestes local markiert werden
- der Aufruf einer Funktion erfolgt einfach durch ihren Namen
Unterschiede von ash/bash
- die mathematische Auswertung erfordert bei der ash die übliche Variablenmarkierung mit dem "$" (innerhalb der doppelten Klammern), während die bash dies nicht verlangt - allerdings wendet die bash bei Anwesenheit des "$" eine komplexere Logik an, auf dass "i=$(($i+1))" wegen unendlicher Rekursion abgelehnt wird
Bock auf mehr?
Dann geh zu: