Was ist der Unterschied zwischen `>> / dev / stderr` (mit dem Leerzeichen) und`> & 2`?

11

In Bash.

Ich habe Schwierigkeiten zu bestimmen, was ich verwenden soll?

Alle meine Skripte verwenden ">> / dev / stderr"

an der Bash-Eingabeaufforderung, wenn ich versuche:
echo test >>/dev/stderrfunktioniert
echo test >> /dev/stderrfunktioniert
echo test >/dev/stderrfunktioniert
echo test > /dev/stderrfunktioniert

echo test >>&2FEHLT!
echo test >> &2FEHLT!
echo test >&2funktioniert
echo test > &2FAILS!

Ich bin bereit, alle meine Skripte zu ändern >&2.

Es scheint auch einen großen Effekt auf ssh (after su SomeUser) zu haben, wo >>/dev/stderres überhaupt nicht funktioniert (Erlaubnis verweigert), sondern nur >&2funktioniert.

Wassermann-Kraft
quelle
Können Sie ein Beispiel für den SSH-Fehler zeigen? Ich kann es nicht reproduzieren.
Jeff Schaller
@ JeffSchaller Sie haben Recht, es ist erst danach, sudass das Problem auftritt , aktualisiert die Frage
Aquarius Power
@AquariusPower, ... um diese Diskrepanz zu erklären: Übrigens: Dieser su -c 'some command'Befehl wird von /bin/shnicht ausgeführt bash, sodass bash-spezifisches Verhalten (z. B. Simulation /dev/stderrfür Umleitungszwecke, wenn es nicht verfügbar ist) nicht garantiert vorhanden ist.
Charles Duffy

Antworten:

22

>& nist die Shell-Syntax zum direkten Duplizieren eines Dateideskriptors . Dateideskriptor 2 ist stderr; So funktioniert das. Sie können auch andere Dateideskriptoren duplizieren, nicht nur stderr. Sie können den Append-Modus hier nicht verwenden, da das Duplizieren eines Dateideskriptors niemals abgeschnitten wird (selbst wenn Ihr stderr eine Datei ist) und >&ein Token ist. Deshalb können Sie kein Leerzeichen darin einfügen - aber es >& 2funktioniert.

>> nameist eine andere zulässige Syntax, wobei nameein Dateiname (und das Token >>) ist. In diesem Fall verwenden Sie den Dateinamen /dev/stderr, was bei betriebssystemspezifischer Behandlung (unter Linux ist dies ein Symlink zu /proc/self/fd/2) auch einen Standardfehler bedeutet. Der Append- und der Truncate-Modus machen beide dasselbe, wenn stderr ein Terminal ist, da dies nicht abgeschnitten werden kann. Wenn Ihr Standardfehler jedoch eine Datei ist, wird sie abgeschnitten:

anthony@Zia:~$ bash -c 'echo hi >/dev/stderr; echo bye >/dev/stderr' 2>/tmp/foo
anthony@Zia:~$ cat /tmp/foo
bye

Wenn bei /dev/stderrover ssh ein Fehler auftritt, hat der Serveradministrator möglicherweise eine Sicherheitsmaßnahme angewendet, die verhindert, dass dieser Symlink funktioniert. (ZB können Sie nicht zugreifen /procoder /dev). Während ich davon ausgehen würde, dass beide Arten von seltsamen Brüchen verursachen, ist die Verwendung der Syntax des doppelten Dateideskriptors ein durchaus vernünftiger (und wahrscheinlich etwas effizienterer) Ansatz. Persönlich bevorzuge ich es.

derobert
quelle
Ich hatte große Probleme beim Versuch, das zuvor abgeschnittene Problem zu wiederholen (sonst hätte ich das der Frage hinzugefügt, hehe), der Grund, warum ich alles geändert habe >>, danke, um darauf hinzuweisen! Außerdem habe ich einen Schritt su SomeUsernach dem Verbinden durch ssh verpasst .
Wassermann Power
das wird bash -c 'echo hi >&2; echo bye >&2' 2>/tmp/foo;cat /tmp/footho nicht abschneiden! (auch mit 2>&1 |tee /tmp/foo) was ist perfekt für die Protokollierung und wird perfekt funktionieren, nachdem ich alles geändert habe >&2. Ich denke also, nur eine direkte Dateiverwendung /dev/stderrerlaubt das Abschneiden, nicht der duplizierte Deskriptor, cool thx!
Wassermann Power
@AquariusPower korrekter, doppelter Dateideskriptor wird nie abgeschnitten. Das ist im ersten Absatz, vielleicht muss ich es irgendwie hervorheben?
Derobert
nicht benötigt, ich bin manchmal langsam ehehe
Aquarius Power
3
Diese Antwort kann verbessert werden. > & ist ein Token, nicht zwei, und da liegt die Verwirrung von OP.
Joshua
8

Die Fehlerfälle treten auf, weil die Bash-Syntax für die Verwendung &in Umleitungen eine einzelne angibt >und erfordert, dass sie direkt neben dem &Zeichen vorhanden ist:

[n]> & Wort

Jeff Schaller
quelle
2

Verwenden Sie '>'diese '>>'Option, um umzuleiten (wird abgeschnitten, falls vorhanden) oder (anhängen, falls vorhanden).

Verwenden Sie '>&'diese Option, um einen Stream zu duplizieren. Wenn Sie beispielsweise eine Standardausgabe UND einen Standardfehler in derselben Datei wünschen, leiten Sie zur Datei um '> output.log'und machen auch Fehler mit'2>&'

myjob.sh > output.log 2>&
Jose Manuel Gomez Alvarez
quelle