Einige Tricks zur Weiterleitung
Einige Syntaxbesonderheiten können dabei wichtige Verhaltensweisen haben. Es gibt einige kleine Beispiele für Umleitungen, STDERR
, STDOUT
und Argumente Bestellung .
1 - Überschreiben oder Anhängen?
Symbol >
bedeutet Nachsendung .
>
bedeutet als ganze abgeschlossene Datei zu senden und überschreibt das Ziel, falls vorhanden (siehe noclobber
bash-Funktion unter #3 später).
>>
bedeutet senden zusätzlich zu würde an das Ziel angehängt, falls vorhanden.
In jedem Fall würde die Datei erstellt werden, wenn sie nicht existiert.
2 - Die Shell-Befehlszeile ist auftragsabhängig!!
Um dies zu testen, benötigen wir ein einfacher Befehl, der auf beiden Ausgängen etwas ausgibt :
$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp
(Vorausgesetzt, Sie haben kein Verzeichnis namens /tnt
natürlich ;). Nun, wir haben es!!
Also, schauen wir mal:
$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1
$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory
Die letzte Befehlszeile speichert STDERR
auf der Konsole, und es scheint nicht das erwartete Verhalten zu sein... Aber...
Wenn Sie etwas machen wollen Nachfilterung über Standard Ausgabe, error Ausgabe oder beides:
$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp --->
$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'
$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
Beachten Sie, dass die letzte Befehlszeile in diesem Absatz genau die gleiche ist wie im vorherigen Absatz, wo ich schrieb scheinen nicht das erwartete Verhalten zu sein (dies könnte also sogar ein erwartetes Verhalten sein).
Nun, es gibt einen kleinen Trick bei Weiterleitungen, denn verschiedene Operationen an beiden Ausgängen durchführen :
$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2 2>&1 | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan 7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory
Nota : &9
Deskriptor würde spontan auftreten, weil ) 9>&2
.
Nachtrag: nota! Mit der neuen Version von bash ( >4.0
) gibt es eine neue Funktion und eine attraktivere Syntax für diese Art von Aufgaben:
$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory
Und schließlich für eine solche kaskadierende Ausgabeformatierung:
$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
1 O: drwxrwxrwt 118 root root 196608 Jan 7 12:29 /tmp
2 E: ls: cannot access /tnt: No such file or directory
Nachtrag: nota! Dieselbe neue Syntax, in beiden Fällen:
$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
1 O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp
2 E: ls: cannot access /tnt: No such file or directory
Wo STDOUT
durch einen speziellen Filter laufen, STDERR
zu einem anderen und schließlich durchlaufen die beiden zusammengefassten Ausgaben einen dritten Befehlsfilter.
2b - Verwendung |&
stattdessen
Syntax command |& ...
könnte als alias para command 2>&1 | ...
. Für die Befehlszeilenreihenfolge gelten dieselben Regeln. Mehr Details unter Was ist die Bedeutung des Operators |& in der Bash?
3 - Ein Wort zu noclobber
Option und >|
Syntax
Das ist ungefähr Überschreiben :
Während set -o noclobber
die Bash anweisen no eine bestehende Datei überschreiben, wird die >|
Syntax können Sie diese Beschränkung überwinden:
$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:15 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:19 CET 2013
$ date > $testfile ; cat $testfile
Mon Jan 7 13:18:21 CET 2013
Die Datei wird jedes Mal überschrieben, also jetzt:
$ set -o noclobber
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan 7 13:18:21 CET 2013
Durchgang mit >|
:
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:18:58 CET 2013
$ date >| $testfile ; cat $testfile
Mon Jan 7 13:19:01 CET 2013
Deaktivieren Sie diese Option und/oder fragen Sie nach, ob sie bereits aktiviert ist.
$ set -o | grep noclobber
noclobber on
$ set +o noclobber
$ set -o | grep noclobber
noclobber off
$ date > $testfile ; cat $testfile
Mon Jan 7 13:24:27 CET 2013
$ rm $testfile
4 - Letzter Trick und mehr...
Zur Umleitung beide Ausgabe eines bestimmten Befehls, sehen wir, dass eine richtige Syntax sein könnte:
$ ls -ld /tmp /tnt >/dev/null 2>&1
für diese Spezial Fall gibt es eine Abkürzungssyntax: &>
... oder >&
$ ls -ld /tmp /tnt &>/dev/null
$ ls -ld /tmp /tnt >&/dev/null
Anmerkung: Wenn 2>&1
existieren, 1>&2
ist ebenfalls eine korrekte Syntax:
$ ls -ld /tmp /tnt 2>/dev/null 1>&2
4b- Nun, ich lasse Sie darüber nachdenken:
$ ls -ld /tmp /tnt 2>&1 1>&2 | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
$ ls -ld /tmp /tnt 1>&2 2>&1 | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/
4c- Wenn Sie interessiert sind an mehr Informationen
Sie können das ausführliche Handbuch lesen, indem Sie auf klicken:
man -Len -Pless\ +/^REDIRECTION bash
in einem bash Konsole ;-)
63 Stimmen
@dbr Ich glaube nicht, dass es nur an der Bash liegt - ich glaube, es ist eine Sache der Bourne-Shell; daher sh, bash, ksh, ash, dash, usw.
8 Stimmen
Dies ist Teil des Umleitungsparagraphen, der POSIX-konforme Shells oder kurz POSIX-Shells beschreibt. ksh ist zum Beispiel eine POSIX-Shell. Siehe: pubs.opengroup.org/onlinepubs/009695399/utilities/
19 Stimmen
Dieses Konstrukt funktioniert auch unter Windows.
7 Stimmen
Es ist im Allgemeinen besser, wenn
2>&1
als 2>/dev/null ;-)18 Stimmen
Ich dachte, ich sollte erwähnen, dass
|&
ist die Kurzform für2>&1 |
wenn Sie zsh benutzen. Ich kann nicht sagen, ob das auch für andere Bourne-ähnliche Shells gilt oder ob es nur eine Funktion von zsh ist.4 Stimmen
@chrixian
|&
ist auch in Bash, eine großartige Funktion. Nicht POSIX scheint es aber (?)2 Stimmen
Sie können diese Antwort überprüfen stackoverflow.com/questions/10508843/what-is-dev-null-21/
0 Stimmen
@chrixian dies ist definitiv in tcsh erforderlich, da
2>^1
funktioniert dort nicht