Die Bourne Again Shell ist ein POSIX-konformer Interpreter für Programme wie dieses:
:(){ :|: & };:
Ein Skript besteht aus einer Folge von Kommandos.
Die erste Zeile kann (und sollte) einen speziellen Kommentar (shebang
)
enthalten, welches den zu verwendenen Interpreter enthält.
hello.sh#!/usr/bin/env bash if [ $# -eq 0 ] then echo Hello, World\! else for arg do echo Hello, $arg\! done fi
Ausführbar machen und ausführen mit:
chmod +x hello.sh && ./hello.sh Hello, World!
Ein Kommando besteht aus dem Namen einer
Funktion oder eines Programms gefolgt von einer Liste mit Argumenten.
In Shellskripten wird die Argumentliste in den Positionsparametern
gespeichert. In C-Programmen greift man auf die Argumentliste über
den Parameter argv
der Funktion main
zu.
Programm | Option | Option | Parameter | Operand | |
Kommandozeile | mkdir | -p | -m | 755 | ~/foo/bar |
Positionsparameter | $0 | $1 | $2 | $3 | $4 |
Argumentliste in C | argv[0] | argv[1] | argv[2] | argv[3] | argv[4] |
Ein Argument,
das mit einem -
beginnt, nennt man Option.
Manche Optionen haben wiederum Parameter (optarg
).
Sie steuern üblicherweise das Verhalten des Programms. Das Programm
getopts
extrahiert alle Optionen aus der Argumentliste.
Übrig bleiben die Operanden, mit denen das Programm arbeitet.
Die Shell verwaltet (wie jeder Prozess) eine Liste von Variablen, die sogenannte Umgebung (environment). Exportierte Variablen vererbt sie an Kindprozesse. Folgende Variablen stehen in jedem Skript zur Verfügung:
0…9
*
"$1 $2 …"
@
"$1" "$2" …
#
?
-
$
!
_
RANDOM
Eine Variable hat einen Namen und einen Wert. Eine Reihung (array) verhält sich wie eine Streutabelle (hashmap) mit numerischen Schlüsseln. Die Bash erlaubt seit Version 4 auch Zeichenketten als Schlüssel.
null= path="/foo/bar.txt" array=(foo bar fnord) declare -A hash=([foo]=fnord [bar]=snafu)
Das Symbol $
steht für Substitution.
Findet die Shell diesen Operator, expandiert sie die entsprechende Variable nach den
unten beschriebenen Regeln, bevor sie das Kommando ausführt.
Variable | Beispiel | Ausgabe | Expansion |
---|---|---|---|
$Name | $path | /foo/bar.txt | Wert der Variable |
${Name} | ${path}_ | /foo/bar.txt_ | Dito |
${Name:Pos} | ${path:4} | bar.txt | Ab dem sovielten Zeichen |
${Name:Pos:Len} | ${path:4:3} | bar | Ab dem sovielten Zeichen mit Länge |
${#Name} | ${#path} | 12 | Länge des Werts |
Ersetzung | |||
${Name#Prefix} | ${path#*/} | foo/bar.txt | Präfix abschneiden |
${Name##Prefix} | ${path##*/} | bar.txt | Präfix gierig abschneiden (basename ) |
${Name%Suffix} | ${path%/*} | /foo | Suffix abschneiden (dirname ) |
${Name%%Suffix} | ${path%%/*} | Suffix gierig abschneiden | |
${Name/Glob/Repl} | ${path/o/l} | /flo/bar.txt | Einmal ersetzen |
${Name//Glob/Repl} | ${path//o/u} | /fuu/bar.txt | Alle ersetzen |
${Name/#Glob/Repl} | ${path/#\/foo/fnord} | fnord/bar.txt | Vorne ersetzen |
${Name/%Glob/Repl} | ${path/%txt/jpg} | /foo/bar.jpg | Hinten ersetzen |
Null-Variable | |||
${Name:+Text} | ${path:+hello} | Alternative oder gar nichts. | |
${Name:-Text} | ${path:-hello} | /foo/bar.txt | Defaultwert |
${Name:=Text} | ${null:=hello} | hello | Defaultwert mit Zuweisung an Variable |
${Name:?Text} | ${null:?hello} | hello | Meldung auf stderr ; beendet die Shell |
Variablennamen | |||
${!Prefix*} | ${!p*} | path | Variablennamen mit Präfix als Token |
${!Prefix@} | ${!p@} | path | Variablennamen mit Präfix als Liste |
Reihung | |||
${Array[*]} | ${array[*]} | foo bar fnord | Werte als Token |
${Array[@]} | ${array[@]} | foo bar fnord | Werte als Liste |
${!Array[*]} | ${!array[*]} | 1 2 3 | Schlüssel als Token |
${!Array[@]} | ${!array[@]} | 1 2 3 | Schlüssel als Liste |
${#Array[@]} | ${#array[@]} | 3 | Anzahl der Elemente |
${#Array[Key]} | ${#array[2]} | 5 | Länge des Elements |
${Array[Key]} | ${array[2]} | fnord | Wert des Elements |
Kommando-Substitution | |||
`Command` | `uname` | Linux | Ausgabe des Kommandos, veraltet |
$(Command) | $(uname) | Linux | Ausgabe des Kommandos |
<(Command) | <(uname) | Ausgabe von Kommando Umleiten | |
>(Command) | >(uname) | Ausgabe zu Kommando Umleiten | |
Arithmetik | |||
$((Expression)) | $((x + 3)) | 8 | Arithmetische Erweiterung |
Wert-Expansion (Klammer, Tilde, Datei) | |||
{Char..Char} | foo{a..c} | fooa foob fooc | Kombinationen mit einer Spanne von Zeichen |
{String,…} | foo{bar,baz} | foobar foobaz | Kombinationen mit einer Liste von Zeichenketten |
~ | ~ | /home/bob | Benutzerverzeichnis des Prozessbesitzers |
~User | ~alice | /home/alice | Benutzerverzeichnis eines anderen Benutzers |
* | foo* | foo foo.txt | Beliebige Zeichenkette |
? | ?oo | foo xoo zoo | Beliebiges Zeichen |
[List] | [a-m,x,y]oo | foo xoo | Ein Zeichen aus einer Gruppe |
Command && Command || Command
if [[ Expression ]]; then …; [ elif [[ Expression ]]; then …; else …; ] fi
case Name in Glob) …;; esac
while [[ Expression ]]; do …; done
until [[ Expression ]]; do …; done
for Name; do …; done
for Name in List; do …; done
for ((Expr1; Expr2; Expr3)); do …; done
break
for
-, while
- oder until
-Schleifecontinue
Name() { … }
return ExitCode
trap Command Signal …
[[ Expression ]]
Operand | Operator | Operand | Wahr, wenn |
---|---|---|---|
Lexikographisch | |||
-z | String | Zeichenkette leer ist | |
-n | String | Zeichenkette mindestens ein Zeichen enthält | |
String | = | String | Zeichenketten identisch sind |
String | == | String | Dito |
String | != | String | Zeichenketten sich unterscheiden |
String | < | String | Linke lexikographisch kleiner als rechte Zeichenkette |
String | > | String | Linke lexikographisch größer als rechte Zeichenkette |
Arithmetisch | |||
! | Expression | Negation, Ausdruck ist falsch | |
Number | -eq | Number | Gleichheit |
Number | -ne | Number | Ungleichheit |
Number | -lt | Number | Linke Zahl kleiner als rechte Zahl |
Number | -le | Number | Linke Zahl kleiner oder gleich rechte Zahl |
Number | -gt | Number | Linke Zahl größer als rechte Zahl |
Number | -ge | Number | Linke Zahl größer oder gleich rechte Zahl |
(( Expression ))
Operand | Operator | Operand | Wahr, wenn |
---|---|---|---|
(…) | Präzedenz | ||
Number | = | Number | Zuweisung |
Number | += | Number | Zuweisung mit Addition |
++ | Number | Increment | |
-- | Number | Decrement | |
~ | Number | Bitkomplement | |
Number | & | Number | Bitweise UND verknüpfen |
Number | ^ | Number | Bitweise ODER verknüpfen |
Number | ** | Number | Exponent |
Number | * | Number | Multiplikation |
Number | / | Number | Division |
Number | % | Number | Modulo |
Number | + | Number | Addition |
Number | - | Number | Subtraktion |
Eine Pipe verbindet die
Standardausgabe eines Prozesses mit der Standardeingabe des Nächsten.
Typische Unix-Programme sind dafür ausgelegt, entweder
als Quelle (cat
, ls
),
als Filter (grep
, sort
)
oder als Senke (less
, lpr
) zu agieren.
Source | Filter | Sink
(Standard)eingabe | |||
---|---|---|---|
Command | [n]< | File | Aus Datei lesen |
Command | [n]<< | Delimiter | Bis zum Trenner lesen (Here-Dokument) |
Command | [n]<<- | Delimiter | Dito, aber Einrückung ignorieren |
Command | [n]<&[n] | Deskriptor duplizieren | |
Command | [n]<&- | Deskriptor schließen | |
(Standard)ausgabe | |||
Command | [n]> | File | In Datei schreiben |
Command | [n]>| | File | Datei überschreiben, selbst wenn noclobber gesetzt ist |
Command | [n]>> | File | An Datei anhängen |
Command | [n]>&[n] | Deskriptor duplizieren | |
Command | [n]>&- | Deskriptor schließen | |
Command | [n]<> | File | Deskriptor zum Lesen und Schreiben öffnen |
0 | Standardeingabe |
1 | Standardausgabe |
2 | Standardfehlerausgabe |
Standardfehlerausgabe im Pager betrachten
Command 2>&1 | less
Der Operator >
leitet die Ausgabe von Kommandos
und Funktionen in Dateien um.
for i in {1..10}; do echo "Hello $i"; done > File
Umgekehrt leitet <
den Inhalt von Dateien
in die Standardeingabe um. Um zum Beispiel eine Datei zeilenweise
zu lesen:
while read line; do echo $((++n)) $line; done < File
Und so leitet man die Standardausgabe eines Kommandos in die Standardeingabe um:
while read line; do echo $line; done < <(Command)
Umleitung eines Here-Dokuments in ein Kommando:
cat <<- . the quick brown fox jumps over the lazy dog .
basic | extended | perl | joe | |
Zeilenanfang | ^ |
^ |
^ |
\^ |
Zeilenende | $ |
$ |
$ |
\$ |
Wortanfang |
|
|
|
\< |
Wortende |
|
|
|
\> |
Beliebiges Zeichen | . |
. |
. |
\? |
Element der Klasse | […] |
[…] |
[…] |
\[…] |
Kein Element | [^…] |
[^…] |
[^…] |
\[^…] |
Buchstabe | [a-zA-Z] |
[:alpha:] |
|
\[a-zA-Z] |
Kleinbuchstabe | [a-z] |
[:lower:] |
|
\[a-z] |
Großbuchstabe | [A-Z] |
[:upper:] |
|
\[A-Z] |
Ziffer | [0-9] |
[:digit:] |
\d |
\[0-9] |
Hexadezimalziffer | [0-9a-fA-F] |
[:xdigit:] |
|
\[0-9A-Fa-f] |
Alphanumerisch | [0-9a-zA-Z] |
[:alnum:] |
|
\[0-9a-zA-Z] |
Wort-Zeichen |
|
[:word:] |
\w |
|
Leerzeichen |
|
[:blank:] |
|
\[ \t] |
Steuerzeichen |
|
[:cntrl:] |
|
\[\x00-\x1F\x7F] |
Unsichtbares Zeichen |
|
[:space:] |
\s |
\[ \t\r\n\v\f] |
Sichtbares Zeichen |
|
[:graph:] |
|
|
Druckbares Zeichen |
|
[:print:] |
|
|
Interpunktion |
|
[:punct:] |
|
|
Gruppierung | \(…\) |
(…) |
(…) |
|
Verweis auf Gruppe | \Num |
|
|
\Num |
Alternative |
|
| |
| |
|
0 oder 1 Vorkommen |
|
? |
? |
|
Beliebig viele Wdh. | * |
* |
* |
\* |
Eine oder mehr Wdh. |
|
+ |
+ |
\+\[…] |
Genau Num Wdh. | \{Num\} |
{Num} |
{Num} |
|
Num bis Num Wdh. | \{Num,Num\} |
{Num,Num} |
{Num,Num} |
|