Kurz: Jedes Programm hat drei Standardkanäle:
Teil des Kurses Bash
Die drei Datenströme
Jedes Programm hat drei Standardkanäle:
| Kanal | Nummer | Bedeutung |
|---|---|---|
stdin | 0 | Eingabe |
stdout | 1 | normale Ausgabe |
stderr | 2 | Fehlermeldungen |
Umleitungen
cd "$(mktemp -d)"
echo "Zeile 1" > datei.txt # überschreiben
echo "Zeile 2" >> datei.txt # anhängen
cat datei.txt
wc -l < datei.txt # Datei als Eingabe
ls /gibt/es/nicht 2> fehler.txt # nur Fehler in Datei
echo "Fehler gespeichert: $(wc -l < fehler.txt) Zeile(n)"
ls /gibt/es/nicht 2>/dev/null # Fehler wegwerfen
echo "stdout" > alles.txt 2>&1 # beide in dieselbe Datei
ls /gibt/es/nicht >> alles.txt 2>&1
wc -l < alles.txt
echo "nur Fehlerausgabe" >&2 # stdout nach stderr umleitenAusgabe:
Zeile 1
Zeile 2
2
Fehler gespeichert: 1 Zeile(n)
2/dev/null verschluckt alles. Die Reihenfolge zählt: > datei 2>&1 (beide in die Datei) ist etwas anderes als 2>&1 > datei.
Pipes
Eine Pipe | verbindet die Ausgabe des einen Programms mit der Eingabe des nächsten:
printf "banane\napfel\nkirsche\napfel\n" | sort | uniq -c | sort -rn
echo "Hallo Welt" | tr 'a-z' 'A-Z' | rev
printf "3\n1\n2\n" | sort -n | head -n 2 | tail -n 1
seq 1 10 | paste -sd+ | bcAusgabe:
2 apfel
1 kirsche
1 banane
TLEW OLLAH
2
55Unix-Philosophie: Jedes Programm macht eine Sache gut, und Pipes kombinieren sie. Der Exit-Status einer Pipe ist standardmäßig der des letzten Befehls; mit set -o pipefail zählt der erste Fehler.
false | true; echo "ohne pipefail: $?"
set -o pipefail
false | true; echo "mit pipefail: $?"
echo "Status einzeln: ${PIPESTATUS[*]}"Ausgabe:
ohne pipefail: 0
mit pipefail: 1
Status einzeln: 0Here-Documents und Here-Strings
cat <<EOF
Hallo $USER_DUMMY
Mehrzeiliger Text mit Variablen: $((1 + 1))
EOF
cat <<'EOF'
Hier wird nichts ersetzt: $HOME $(date)
EOF
wc -w <<< "ein Here-String mit fünf Wörtern"
cat <<-EOF
Eingerückte Zeilen (Tabs) werden bei <<- entfernt
EOFAusgabe:
Hallo
Mehrzeiliger Text mit Variablen: 2
Hier wird nichts ersetzt: $HOME $(date)
5
Eingerückte Zeilen (Tabs) werden bei <<- entfernttee, xargs und Prozess-Ersetzung
cd "$(mktemp -d)"
echo "Daten" | tee ausgabe.txt | tr a-z A-Z # an Datei und weiter
cat ausgabe.txt
printf "a\nb\nc\n" | xargs -I{} echo "Verarbeite {}"
printf "1 2 3\n" | xargs -n1 | paste -sd,
echo "ein Argument mit Leerzeichen" | xargs printf "[%s]\n"
diff <(printf "a\nb\n") <(printf "a\nc\n") # Ausgaben wie Dateien vergleichen
comm -12 <(printf "a\nb\nc\n") <(printf "b\nc\nd\n")Ausgabe:
DATEN
Daten
Verarbeite a
Verarbeite b
Verarbeite c
1,2,3
[ein]
[Argument]
[mit]
[Leerzeichen]
2c2
< b
---
> c
b
cHintergrundprozesse und Jobs
sleep 0.2 &
pid=$!
echo "Hintergrundprozess läuft: $(kill -0 $pid 2>/dev/null && echo ja || echo nein)"
wait $pid
echo "fertig, Status $?"
( sleep 0.1; echo "Teil A" ) &
( sleep 0.2; echo "Teil B" ) &
wait
echo "alle fertig"Ausgabe:
Hintergrundprozess läuft: ja
fertig, Status 0
Teil A
Teil B
alle fertigWeitere nützliche Werkzeuge: jobs, fg, bg, Strg+Z (anhalten), Strg+C (abbrechen), nohup, disown, timeout 5 befehl.
Merke
>überschreibt,>>hängt an,<liest,2>leitet Fehler um,2>&1führt zusammen|verbindet Programme;set -o pipefailmeldet Fehler in der Pipe- Here-Document
<<EOF, Here-String<<< tee,xargs,<(...)erweitern die Möglichkeiten&startet im Hintergrund,waitwartet
Übungsaufgabe
Zähle mit einer Pipe die Dateien eines Ordners nach Endung (ls | sed ... | sort | uniq -c).
Quiz zur Selbstkontrolle
Was bewirkt 2>&1?
- Fehlerausgabe geht dorthin, wohin die normale Ausgabe geht (richtig)
- Beides wird gelöscht
- Nur Fehler werden angezeigt
- Die Ausgabe wird verdoppelt
Wozu dient set -o pipefail?
- Eine Pipe schlägt fehl, wenn irgendein Teil fehlschlägt (richtig)
- Pipes werden schneller
- Pipes sind verboten
- Ausgabe wird sortiert
Was macht cmd &?
- Startet den Befehl im Hintergrund (richtig)
- Führt ihn zweimal aus
- Wartet auf ihn
- Bricht ihn ab
Weiter im Kurs
Zurück: Arrays, Maps und String-Operationen
Weiter: grep, sed, awk und Co.
Alle Kapitel: Bash im Überblick