Ein- und Ausgabeverarbeitung: Unterschied zwischen den Versionen
Michi (Diskussion | Beiträge) (→Befehlsausgabeumleitung) |
Michi (Diskussion | Beiträge) (→Befehlsausgabeumleitung) |
||
(5 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 4: | Zeile 4: | ||
{| class=wikitable | {| class=wikitable | ||
− | ! | + | ! Dateideskriptor || Name || Bedeutung || Standardbelegung || Zeichen |
|- | |- | ||
| 0 || <tt>stdin</tt> || Standardeingabe || Tastatur || < | | 0 || <tt>stdin</tt> || Standardeingabe || Tastatur || < | ||
|- | |- | ||
− | | 1 || <tt>stdout</tt> || Standardausgabe || Terminal / Bildschirm || > | + | | 1 || <tt>stdout</tt> || Standardausgabe || Terminal / Bildschirm || ><br>1> |
|- | |- | ||
| 2 || <tt>stderr</tt> || Standardfehlerausgabe || Terminal / Bildschirm || 2> | | 2 || <tt>stderr</tt> || Standardfehlerausgabe || Terminal / Bildschirm || 2> | ||
Zeile 154: | Zeile 154: | ||
${ACKER} | ${ACKER} | ||
<b>EOF</b> | <b>EOF</b> | ||
+ | |||
+ | Umleitung der vollständigen Ausgabe oder eines Teils der Ausgabe eines Skripts in eine Datei. | ||
+ | * https://stackoverflow.com/questions/314675/how-to-redirect-output-of-an-entire-shell-script-within-the-script-itself | ||
+ | * https://tldp.org/LDP/abs/html/special-chars.html#CODEBLOCKREF | ||
+ | * https://ops.tips/gists/redirect-all-outputs-of-a-bash-script-to-a-file/ | ||
+ | |||
+ | #!/bin/bash | ||
+ | |||
+ | # ...Teil des Skripts ohne Ausgabeumleitung... | ||
+ | |||
+ | # code block | ||
+ | { | ||
+ | # ...Teil des Skripts mit Ausgabeumleitung | ||
+ | } > ausgabe 2> fehler # auch möglich: > ausgabe 2>&2 | ||
+ | |||
+ | # ...weiterer Teil des Skripts ohne Ausgabeumleitung... | ||
=== Here-Dokument === | === Here-Dokument === |
Aktuelle Version vom 26. Juli 2021, 10:03 Uhr
Ein- und Ausgabeverarbeitung / EAV (engl. Input/Output / I/O)
Lese- und Schreiboperationen an Dateien werden auf Unix-Betriebssystemen über numerierte Kanäle (Dateideskriptoren) abgehandelt. Möchte ein Programm eine Datei öffnen, um daraus zu lesen, so erhält es eine Nummer, über die es mit der gewünschten Datei arbeiten kann. Die ersten drei Dateideskriptoren sind für Standardwerte reserviert.
Dateideskriptor | Name | Bedeutung | Standardbelegung | Zeichen |
---|---|---|---|---|
0 | stdin | Standardeingabe | Tastatur | < |
1 | stdout | Standardausgabe | Terminal / Bildschirm | > 1> |
2 | stderr | Standardfehlerausgabe | Terminal / Bildschirm | 2> |
Anwendungen von "stdin" und "stdout" sind Befehlsweiterleitungen und Befehlsumleitungen.
Inhaltsverzeichnis
Befehlsgruppierung
Durch die runden Klammern "()" oder die geschweiften Klammern "{}" lassen sich Befehle gruppieren.
In einer Subshell wird der zuerst der erste Befehl ("cd /tmp"), danach der zweite ("ls") ausgeführt. Nach Abarbeitung beider Befehle befindet man sich also immer noch im ursprünglichen Verzeichnis.
$ (cd /tmp; ls)
Zusätzlich wird das Ergebnis in die Datei "outfile" im aktuellen Verzeichnis geschrieben.
$ (cd /tmp; ls) > outfile
In der aktuellen Shell wird zuerst der erste Befehl ("cd /tmp"), danach der zweite ("ls") ausgeführt. Nach Abarbeitung des ersten Befehls befindet man sich im Verzeichnis "/tmp" und bleibt auch dort. Zu beachten ist auch der Strichpunkt nach dem zweiten Befehl.
$ { cd /tmp; ls; }
Befehlstrenner
Neben "Carriage return" sind auch die Zeichen ";" und "&" sogenannte Befehlstrenner (engl. command separator).
Zuerst wird der erste Befehl ("date") ausgeführt, danach unabhängig vom ersten der zweite ("who").
$ date; who
Der erste Befehl ("du -s /") wird im Hintergrund ausgeführt, der zweite ("who") dagegen sofort.
$ du -s / & who
Befehlsverknüpfung
Anstatt mehrere Befehle einzeln abzusetzen, können diese Befehle durch Strichpunkte (";") getrennt auch auf einer Zeile geschrieben werden und werden direkt hintereinander ausgeführt.
$ mkdir directory2 $ cd directory2 $ cp ../directory1/* .
ist also gleichwertig mit
$ mkdir directory2; cd directory2; cp ../directory1/* .
Ebenso ist es möglich, einen zweiten Befehl nur dann auszuführen, wenn der vorangehende Befehl erfolgreich war. Beispielsweise prüft der Befehl test, ob die Datei "file" existiert und schreibbar ("-w") ist - falls dies zutrifft, wird sie durch den Befehl rm gelöscht.
$ test -w file && rm file
Beispielsweise kann mit dem Befehl test auch geprüft werden, ob das Verzeichnis ("-d") "directory" vorhanden ist. Nur falls das nicht zutrifft, wird es mit dem Befehl mkdir erstellt.
$ test -d directory || mkdir directory
Beim Installieren neuer Software aus den Quellen kann der übliche Dreierschritt aus "./configure", "make" und "make install" derart verbunden werden, dass jeder folgende Befehl nur dann weitermacht, wenn der vorangehende keine Fehler produziert hat.
# ./configure && make && make install
Befehlsweiterleitung
Bei der Weiterleitung eines Befehls wird die Standardausgabe ("stdout") des eines Befehls (anstatt an die Konsole) in den Eingabekanal ("stdin") des nächsten Befehls geschickt. So entsteht eine sogenannte "Leitung" (engl. pipe). In einer Befehlszeile können beliebig viele Befehle mit solchen "Leitungen" verknüpft werden - diese "Leitungen" sind der Hauptgrund für den Erfolg und die Beliebtheit der Shell.
Jeder Befehl der Befehlsweiterleitung wird dabei in einer eigenen Subshell als eine Art Unterprozess ausgeführt. Das geschieht für alle Befehle parallel - Daten gehen in einer Befehlsweiterleitung aber keine verloren, da langsamere Prozesse die schnelleren wenn nötig bremsen. Die Rückgabewerte sämtlicher Befehle der Befehlsweiterleitung werden in der Variable "PIPESTATUS" abgelegt.
Beispiel:
$ ls -al | grep abc $ echo $PIPESTATUS 0
Anzeige einer Liste der Dateien im Verzeichnis "/usr/bin", wobei nur die Dateien angezeigte werden (keine Verzeichnisse), wobei eine umgekehrte numerische Sortierung am Ende des vierten Felds nach dem fünften Feld (Dateigrösse) stattfindet, wobei nur die erste Zeile (also diejenige mit der grössten Dateigrösse) ausgegeben wird, wobei nur das achte Feld (der Dateiname) angezeigt wird.
$ ls -l /usr/bin | grep ^- | sort -nr +4 -5 | head -1 | awk '{ print $8 }'
Finden aller Dateien mit Endung "jpg" und Einfärben dieser Endung in der Ergebnisliste.
$ find . -name "*jpg" | grep --color jpg ./back.jpg ./front.jpg
Umlenkung der Ausgabe mittels tee in mehrere Dateien sowie auf den Bildschirm.
Befehl | tee Datei Datei
Beispiel:
$ who | tee eingeloggt.txt | grep mik $ tar cvf backup.tar * | tee backup.log
Befehlsausgabeumleitung
Umlenkung der Standardausgabe in eine Datei. Besteht bereits eine Datei mit diesem Namen, wird sie ohne Vorwarnung überschrieben. Dieses Verhalten lässt sich ab der Korn-Shell mit dem Befehl "set -o noclobber" ändern. Damit die Shell ungeachtet dieser Einstellung eine bestehende Datei gleichen Namens überschreibt, kann > |
verwendet werden.
Befehl > Datei bzw. Befehl 1> Datei
Umlenkung aller vom betreffenden Dateideskriptor bezeichneten Kanal ankommenden Zeichen in eine Datei.
Befehl Dateideskriptor > Datei
Umleitung der Standardausgabe von Befehl ls in die Datei "index", während die Standardfehlerausgabe ins virtuelle Datennirwana "/dev/null" geschrieben wird.
$ ls > index 2> /dev/null
Umlenkung von der Standard- und der Standardfehlerausgabe in eine die Datei.
Befehl &> Datei
Umlenkung von der Standardausgabe in eine Datei. Besteht bereits eine Datei mit diesem Namen, so wird die Standardausgabe an diese Datei angehängt.
Befehl >> Datei
Umlenkung der Ausgaben eines Dateideskriptors auf einen anderen Dateideskriptor oder auf eine andere Datei.
Befehl Dateideskriptor >& Dateideskriptor oder Datei
Standard- und Standardfehlerausgabe des Befehls ls werden in dieselbe Datei umgeleitet.
$ ls > datei 2>&1 oder $ ls > datei_stdout 2> datei_stderr 2>&1
Umleitung der Ausgabe "Fehler" in die Standardfehlerausgabe.
$ echo "Fehler" >&2
Umleitung der Standardfehlerausgabe des Befehls ls ins Datennirwana ("/dev/null") um und leitet gleichzeitig auch die Standardausgabe auf die Standardfehlerausgabe um. Im Fehlerfall wird also nichts am Bildschirm angezeigt.
$ ls -l /tmp 2> /dev/null >&2
Inhalt einer Datei an die Eingabe (stdin) eines Programms schicken.
Befehl Dateideskriptor < Datei
Beispiele:
$ cat < datei $ mail -s "brief" mik < brieftext
Befehl Dateideskriptor <& Dateideskriptor oder Datei
ACKER=$(echo 'unload to ...;') $ isql siasdb - <<EOF ${ACKER} EOF
Umleitung der vollständigen Ausgabe oder eines Teils der Ausgabe eines Skripts in eine Datei.
- https://stackoverflow.com/questions/314675/how-to-redirect-output-of-an-entire-shell-script-within-the-script-itself
- https://tldp.org/LDP/abs/html/special-chars.html#CODEBLOCKREF
- https://ops.tips/gists/redirect-all-outputs-of-a-bash-script-to-a-file/
#!/bin/bash # ...Teil des Skripts ohne Ausgabeumleitung... # code block { # ...Teil des Skripts mit Ausgabeumleitung } > ausgabe 2> fehler # auch möglich: > ausgabe 2>&2 # ...weiterer Teil des Skripts ohne Ausgabeumleitung...
Here-Dokument
Das Here-Dokument ist ein Spezialfall der Befehlsumleitung. Es handelt sich um ein elegantes Mittel, um Konfigurationsdateien oder kurze Texte direkt in Skripte einzubetten. "stdin" wird dabei bis zur zuvor angegebenen Markierung eingelesen. Die Bash übernimmt den Text einschliesslich Zeilenumbrüchen und expandiert sogar Variablen.
"stdin" wird bis zur Markierung "EOF" gelesen.
$ cat << EOF Hallo Welt EOF
"stdin" wird bis zur Markierung "EOF" gelesen. Mit der Variante "<<-" darf die Eingabe zur besseren Lesbarkeit sogar eingerückt werden - die Bash entfernt die Zeichen später.
#!/bin/bash for i in anna berta carola do cat <<- EOF | mail Einladung "${i}@beispiel.xx" Liebe ${i} Kommst Du zu meinem Geburtstag? Ich freue mich! XOX EOF done
Das folgende Skript "telefon" beinhaltet Programm und Daten. grep liest dabei "stdin" bis zur Markierung "END".
$ cat > telefon grep -i "$*" << END Chef 102938 Karin 674839 Esther 123456 Schwester 987654 Buero 172839 END CTRL+D $ chmod +x telefon $ ./telefon chef Chef 102938
Weblinks
Herausgeber | Sprache | Webseitentitel | Anmerkungen |
---|---|---|---|
![]() |
eng | Enzyklopädischer Artikel |