Windows-Cmd-Ausgabeumleitung zur Standardeingabe (> & 0)

4

Aufgrund einer Frage zu Stackoverflow teste ich mit der Umleitung von / zu STDIN-Stream. Und diese Tests, bei denen versucht wird, Daten an den Standard-Stream zu senden, um zu sehen, was passiert, enden mit einem scheinbar chaotischen Verhalten.

Befehle wie

echo testing >&0
dir >&0 
cls >&0

wird einen generieren System can not write to the specified device(scheint, dass stdin ein schreibgeschützter Stream ist, vielleicht), aber Dinge wie

  • vol >&0 zeigt keinen Fehler an

  • set /p "var=prompt" >&0 Wartet auf die Eingabe, während die Eingabeaufforderung nicht angezeigt wird und kein Fehler angezeigt wird

  • pause >&0 wird ohne Fehler warten, aber wenn eine Taste gedrückt wird, wird ein Fehler angezeigt

Und der letzte Strohhalm ist stderr Umleitung. Wenn Sie interne Befehle verwenden, die die Ausgabe an stderr senden, wobei die Ausgabe an stdin umgeleitet wird, wie z

call "noFile" 2>&0
dir  "|" 2>&0

das Ergebnis ist, dass cmd.exe geschlossen wird. Aber nicht immer. Dinge wie

dir "|" * 2>&0
dir * "|" 2>&0

Arbeiten Sie ohne Probleme, verstecken Sie den an stderr gesendeten Text und drucken Sie den Rest der Informationen aus.

Die Frage ist also, ist dies ein Fehler, ist er irgendwo dokumentiert und ich kann ihn nicht finden oder ist dies das erwartete Verhalten und es gibt etwas Offensichtliches, das mir fehlt?

MC ND
quelle

Antworten:

4

Da CMD.EXE leider nicht ausreichend dokumentiert ist, bin ich mir nicht sicher, wie das erwartete Verhalten aussehen soll. Ich habe sicherlich keine Dokumentation darüber gesehen, was das erwartete Verhalten ist. Ich denke, es wird Ihnen schwer fallen, jemanden zu finden, der eine endgültige Antwort darauf gibt, ob eines der Verhaltensweisen ein Fehler ist. Aber ich bin damit einverstanden, dass es sicherlich inkonsistent ist und mir zumindest als Designfehler erscheint.

Ich würde die Situation nicht als chaotisch bezeichnen, da das Verhalten eines bestimmten Befehls reproduzierbar zu sein scheint. Aber CMD.EXE ist insofern inkonsistent, als ich keine Möglichkeit sehe, vorherzusagen, wie sich ein Befehl verhält, ohne zu testen.

Ich habe keine Erklärungen, aber ich habe einige verfeinerte Klassifikationen von Verhaltensweisen.

Die Umleitung von stdout oder stderr nach stdin funktioniert einwandfrei, solange kein Befehl tatsächlich versucht, etwas in die umgeleitete Ausgabe zu schreiben. Das seltsame Verhalten tritt nur auf, wenn ein interner Befehl versucht, nach stdout oder stderr zu schreiben, nachdem er nach stdin umgeleitet wurde.

Ich habe Ihre Tests erweitert und die folgenden unterschiedlichen Verhaltensweisen festgestellt:

Umgeleitete STDERR 2>&01

Ich habe keine umfassenden Tests durchgeführt, aber jeder interne Befehl, den ich getestet habe und der in stderr schreibt, beendet die Befehlssitzung sofort, wenn stderr zu stdin umgeleitet wurde. Beispiele beinhalten:

cd invalidPath 2>&0
vol x 2>&0
copy nonExistentFile 2>&0
move nonExistentFile 2>&0
set nonExistentVariable 2>&0
dir nonExistentFile 2>&0

Was Sie für eine Ausnahme hielten, schreibt eigentlich nie an stderr. Versuchen Sie Folgendes ohne Umleitung, und es wird keine Fehlermeldung angezeigt:

dir nonExistentFIle *

Es gibt also keinen Grund für den Befehl, die Befehlssitzung zu beenden, wenn stderr zu stdin umgeleitet wird.

DIR gibt nur dann eine Fehlermeldung aus, wenn keine übereinstimmende Datei in allen bereitgestellten Dateimasken gefunden wird.

:: This prints an error message
dir nonExistentFile1 nonExistentFile2

:: So this terminates the command session
dir nonExistentFile1 nonExistentFile2 2>&0


Umgeleitete STDOUT 1>&0

Hier sind die Verhaltensweisen, die ich für umgeleitete Standardausgabe gesehen habe:

1) Der Ausgang verschwindet ohne Fehlermeldung im Äther.

Beispiele:

vol >&0
copy /-y file1 existingFile2 >&0
move /-y file1 existingFile2 >&0


2) Die Ausgabe schlägt fehl und stderr wird eine Fehlermeldung angezeigt. Ein einzelner Befehl kann mehrere Fehlermeldungen erzeugen, eine für jeden fehlgeschlagenen Versuch, in stdout zu schreiben.

Beispiele:

cd >&0
echo Hello >&0

:: This generates 2 error messages, one for the time,
:: and another for the subsequent empty line
time /t >&0


3) Die Ausgabe schlägt fehl und die Stapelverarbeitung wird beendet. Active SETLOCAL bleibt auch nach dem Batch-Abbruch wirksam, wenn der Fehler innerhalb einer CALLed-Subroutine auftritt. In dieser Hinsicht verhält es sich ähnlich wie ein schwerwiegender Syntaxfehler.

Bisher habe ich nur einen Befehl gesehen, der dieses Verhalten aufweist:

dir >&0

Ich würde erwarten, dass der Befehl DIR eine Fehlermeldung für jede versuchte Ausgabezeile generiert. Es scheint jedoch nach einem Fehler in der ersten Zeile zu enden, und die Stapelverarbeitung wird ebenfalls abgebrochen.


4) Einige Befehle weisen mehrere Verhaltensweisen auf.

Beispiele:

:: This SET command generates an error message for each
:: defined variable (behavior 2)
set >&0

:: But this SET command fails to display the prompt without
:: error message (behavior 1). Note that the echo of user input
:: is written directly to :con. It does not use stdout or stderr.
set "var=prompt" >&0

:: A single PAUSE exhibits both behaviors 1 and 2. The prompt to
:: press a key simply dissapears, and the echo of the user input
:: generates an error. Note that in this case, the echo of user
:: input is written to stdout.
pause >&0
dbenham
quelle
Na sicher. Ich konnte nicht sehen, dass der dirBefehl nicht nach stderr schreibt, wenn etwas gefunden wird. Und ja, inkonsistent ist der genaue Begriff, danke.
MC ND
0

Ich habe diesen Fehler 2010 zum ersten Mal versehentlich entdeckt. Letztendlich habe ich meinen Fehler entdeckt - die Umleitung von stderr auf Stream 0 (stdin für den aktuellen Prozess) macht keinen logischen Sinn, und cmd.exe hatte keinen Handler für dieses Szenario aus. Die korrekte Syntax lautete:

dir 2> nul (wenn ich nur den Fehler umleiten wollte)

oder

dir 2> nul 1> & 2 (wenn ich auch die erfolgreiche Ausgabe umleiten wollte).

Grundsätzlich nur eine unbehandelte Ausnahme in CMD.EXE für alle eingebauten Befehle. Hier ist mein Bericht von vor ein paar Jahren: http://dnlongen.blogspot.com/2013/05/how-to-crash-windows-shell.html

David Longenecker
quelle
Danke dir. Das war kein Fehler. Wie Sie habe ich manchmal die Möglichkeit / Zeit, den Debugger an etwas anzuhängen und zu spielen. Ich weiß (aus früheren Tests), dass der Befehlsprozessor direkt beendet wird, wenn er nicht in der Lage ist, in stderr zu schreiben (das sollte nicht passieren). Was ich nicht gesehen habe, ist, warum es "manchmal" nicht passiert ist. Als dbenham darauf hinwies, was ich nicht sah, war, dass meine "problematischen" Fälle nicht an stderr schrieben.
MC ND
0

Besuchen Sie https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true (archiviert)

>& Writes the output from one handle to the input of another handle.
<& Reads the input from one handle and writes it to the output of another handle.

Der & Umleitungsoperator dupliziert die Ausgabe oder Eingabe von einem angegebenen Handle zu einem anderen angegebenen Handle. Wenn Sie ein Handle duplizieren, duplizieren Sie alle Merkmale des ursprünglichen Vorkommens des Handles. Wenn ein Handle beispielsweise nur Schreibzugriff hat, haben alle Duplikate dieses Handles nur Schreibzugriff. Sie können ein Handle mit schreibgeschütztem Zugriff nicht in ein Handle mit schreibgeschütztem Zugriff duplizieren.

joanmib
quelle
Bitte lesen Sie die Frage noch einmal sorgfältig durch. Ihre Antwort beantwortet nicht die ursprüngliche Frage. Sie machen keinen Versuch, eines der seltsamen Verhaltensweisen in der Frage des OP zu erklären. Bitte lesen Sie die akzeptierte Antwort, um zu sehen, wie eine gute Antwort aussieht.
DavidPostill
Ups, meine Schuld, Sie haben Recht: Meine Antwort erklärt nicht, warum manchmal Fehler zurückgegeben werden und manchmal nicht oder abstürzen. Es weist darauf hin, dass immer ein Fehler (das "kann nicht schreiben ...") als erwartetes Verhalten zurückgegeben werden sollte, daher scheint es ein Fehler zu sein, wie @ David-Longenecker unten sagt und in seinem Blog dnlongen.blogspot.com/2013/05/how-to erklärt -crash-windows-shell.html
Joanmib