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
dir
Befehl nicht nach stderr schreibt, wenn etwas gefunden wird. Und ja, inkonsistent ist der genaue Begriff, danke.