Schreiben der Befehlsausgabe in Windows cmd in eine Datei (mit einem Dreh)

9

Ich versuche also zu laufen foo.exe, aber ich möchte nicht, dass die Ausgabe an das Terminal, sondern in eine Datei erfolgt. Laufen foo.exe > foo.txtsollte dies für mich erreichen, ist es aber nicht. Wenn ich die exe-Datei ausführe, erhalte ich die Ausgabe. Die Exe funktioniert also gut. Wenn ich jedoch versuche, die Ausgabe an eine Datei zu senden, erhalte ich nur Folgendes:

'c:/Program' is not recognized as an internal or external command,
operable program or batch file.

Dies wird nur angezeigt, wenn ich versuche, es an eine Datei zu senden. Da ich dachte, dass es der Pfad (der ist c:\Program Files (x86)\usw.) sein könnte, der falsch interpretiert wird, habe ich versucht, die Ausgabedatei so anzugeben: foo.exe > c:\test.txtaber immer noch keine Freude.

Kann ich, abgesehen von der Feststellung, dass die Binärdatei, die ich ausführen möchte, schlecht geschrieben ist, irgendetwas tun, um dies zu beheben? Denken Sie daran, dass ich beim Ausführen der Exe eine gültige Ausgabe erhalte. Sie wird einfach nicht gut in eine Datei gedruckt. Offensichtlich ist die Ausgabe da, die Frage ist, ob es eine Möglichkeit gibt, sie zu fangen.

pzkpfw
quelle
Was passiert, wenn Sie das Programm in ein einfaches Verzeichnis (C: \ Simple oder sogar C: \) verschieben und diese Dinge von dort aus ausprobieren?
Jan Doggen

Antworten:

21

Sie haben den von Ihnen verwendeten Befehl nicht angezeigt, der fehlschlägt. Wenn Sie es in Ihrer Frage zeigen, ist es möglicherweise einfacher, eine Lösung für Sie zu finden.

Ich gehe davon aus, dass Ihr Befehl ungefähr so ​​lautet:

C:\>foo.exe|c:\Program Files (x86)\something\test.txt

Der Fehler, den Sie erhalten, ist ein Hinweis:

'c:/Program' is not recognized as an internal or external command, operable program or batch file.

Zuerst:
... is not recognized as an internal or external command, operable program or batch file.

Dies geschieht normalerweise, wenn Sie versuchen, mit a |anstelle von a zu einer Datei umzuleiten >.

Zweite:
'c:/Program' ...

Wenn Sie einen Dateinamen (oder Pfad) angeben, der Leerzeichen enthält, müssen Sie ihn in doppelte Anführungszeichen ( "...") setzen. Dies liegt daran, dass das Betriebssystem beim Festlegen der Datei, zu der umgeleitet werden soll, nicht mehr nach dem Dateinamen sucht, wenn es auf ein nicht angegebenes Leerzeichen stößt : "c:/Program".

Versuche dies:

foo.exe>"c:\Program Files (x86)\something\test.txt"



Wenn das oben Gesagte nicht funktioniert, um die Ausgabe aus foo.exeder Textdatei zu erfassen , gibt es eine andere Möglichkeit ...

Wenn das Programm foo.exeseine Ausgabe STDERRanstelle von schreibt STDOUT, wird die Ausgabe von foo.exenicht durch einfache Umleitung mit einer einzelnen erfasst >. Sie müssten es so machen:

foo.exe>"c:\Program Files (x86)\something\test.txt" 2>&1



Bearbeiten:

Hier finden Sie eine Erläuterung der Dateiumleitung und der 2>&1Notation.

Wenn ein Programm in das Terminal schreibt, kann es in eines von zwei schreiben Streams.

  1. Stream 1 wird als STDOUToder Standardausgabe bezeichnet . Normalerweise schreiben Programme ihre "normale" Ausgabe in Stream 1.

  2. Stream 2 wird als STDERRoder Standardfehler bezeichnet . Normalerweise schreiben Programme ihre "Fehler" -Ausgabe (Fehler- und Warnmeldungen) in Stream 2.

Ob ein Programm eine bestimmte Ausgabe in den Programmierer schreibt STDOUToder von diesem STDERRbestimmt wird und wie er das Programm geschrieben hat. Einige Programme sind so geschrieben, dass sie alle Ausgaben (normale Ausgaben und Fehler) an senden STDOUT.

Wenn ein Programm ohne Ausgabeumleitung ausgeführt wird, werden alle normalen und Fehlerausgaben an den Terminalbildschirm gesendet, ohne dass zwischen STDOUTAusgabe und STDERRAusgabe unterschieden wird.

Wenn Sie eine "normale" Umleitung mit einer Single >wie dieser durchführen:

foo.exe > "c:\Program Files (x86)\something\test.txt"

Sie geben nicht an, welcher Stream in die Datei umgeleitet wird, daher wird Stream 1 angenommen.

Es ist das gleiche, als ob Sie es so eingegeben hätten:

foo.exe 1> "c:\Program Files (x86)\something\test.txt"

Dies weist den Befehlsinterpreter ( cmd.exe) an, die Programmausgabe für STDOUT(Stream 1) unter dem angegebenen Dateinamen zu erfassen . Das 1in 1>bezieht sich auf Stream 1.

In diesem Fall wird das gesamte normale Programm in die Datei aufgenommen. Wenn das Programm jedoch in STDERR(Stream 2) schreibt , wird diese Ausgabe nicht erfasst und auf dem Bildschirm angezeigt. Dies ist im Allgemeinen die "gewünschte" Methode, damit Sie während der Erfassung der normalen Programmausgabe auf dem Bildschirm sehen können, ob ein Fehler auftritt.

Wenn Sie die Ausgabe "Normal" in eine Datei und die Ausgabe "Fehler" in eine andere Datei erfassen möchten, gehen Sie folgendermaßen vor:

    foo.exe > "c:\output.txt" 2> "C:\error.txt"
or
    foo.exe 1> "c:\output.txt" 2> "C:\error.txt"

Wenn Sie möchten, dass die Ausgabe "Normal" und die Ausgabe "Fehler" in derselben Datei erfasst werden, können Sie dies wie folgt angeben:

foo.exe > "c:\output.txt" 2>&1

Dies ist im Grunde eine "Kurzform" für die Angabe und bedeutet, Stream 1 in die angegebene Datei umzuleiten und Stream 2 an denselben "Ort" (Datei) wie Stream 1 umzuleiten .


Bearbeiten:

Pacerier fragte:

Gibt es einen Unterschied zwischen foo.exe> ​​"c: \ output.txt" 2> & 1 und foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt"? Sind sie identisch?

Kurze Antwort: Sie würden denken, dass sie identisch sind, aber nein. Sie sind anders.

Bei Umleitung mit >"filename.ext", 1>"filename.ext"oder 2>"filename.ext", >wird die Ausgabe in eine neue Datei mit dem Namen "filename.ext" geschrieben. Wenn die Datei "filename.ext" bereits vorhanden ist, wird sie zuerst gelöscht.

Also mit:

foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt"

verursacht einen "Konflikt", bei dem beide Umleitungen versuchen, in dieselbe Datei zu schreiben, und beide versuchen, die Datei zu löschen, falls sie bereits vorhanden ist. Dies wird wahrscheinlich zu unerwünschtem Verhalten führen. Im Allgemeinen werden der eine oder der andere oder beide Ausgänge NICHT vollständig oder vorhersehbar erfasst.

Das tatsächliche Ergebnis hängt vom Betriebssystem und der Version ab und kann auch vom ausgeführten Befehl abhängen. Was wahrscheinlich passieren wird, ist:

1 Die an eine der Umleitungen gesendete Ausgabe wird erfasst oder teilweise erfasst, und die an eine andere Umleitung gesendete Ausgabe geht verloren. 2 Das Betriebssystem beschwert sich über den Befehl und keiner der Ausgänge wird (vollständig) erfasst. 3 Undefiniertes, unerwünschtes, unvorhersehbares, unerwartetes Verhalten.

Unter Windows 7 und wahrscheinlich unter Windows Vista / 8/10 und möglicherweise unter Windows XP beschwert sich das Betriebssystem über den Befehl und der Befehl wird abgebrochen.

Zum Beispiel (Windows 7): Ich habe einen Ordner mit dem Namen: "C:\Temp\emptyfolder"und eine Datei mit dem Namen "nonexistantfile" existiert dort nicht.

C:\>cd "\Temp\emptyfolder"

C:\Temp\emptyfolder>dir nonexistantfile>output.txt
File Not Found

C:\Temp\emptyfolder>type output.txt
 Volume in drive F is FFFFx1tb
 Volume Serial Number is 4011-A5C6

 Directory of C:\Temp\emptyfolder

C:\Temp\emptyfolder>

In diesem Fall wird mit einer Umleitung ( >output.txt) die Ausgabe des dirBefehls in der Datei erfasst: output.txtund die Fehlermeldung File Not Foundwird auf dem Bildschirm angezeigt. Dies ist das erwartete Verhalten.

Verwenden Sie nun beide Umleitungen ("> Datei" UND "2> Datei"):

C:\Temp\emptyfolder>dir nonexistantfile>output.txt 2>output.txt
The process cannot access the file because it is being used by another process.
C:\Temp\emptyfolder>type output.txt

C:\Temp\emptyfolder>

In diesem Fall hat das Betriebssystem beanstandet, dass die (Outout-) Datei bereits verwendet wird. Die Datei "output.txt" ist leer (0 Byte) und die Ausgabe für beide Umleitungen ging verloren.

Verwenden Sie zum Schluss beide Umleitungen ("> Datei" UND "2> & 1"):

C:\Temp\emptyfolder>dir nonexistantfile>output.txt 2>&1

C:\Temp\emptyfolder>type output.txt
 Volume in drive C is CCCCCCCC
 Volume Serial Number is 1234-ABCD

 Directory of C:\Temp\emptyfolder

File Not Found

C:\Temp\emptyfolder>

In diesem Fall bewirkt "> Datei", dass die Ausgabe für "Stream 1" ("Standardausgabe") in der Datei erfasst wird. Und "2> & 1" bewirkt, dass die Ausgabe für "Stream 2" ("Fehlerausgabe") über den bereits umgeleiteten "Stream 1" gesendet und auch in die (gleiche) Datei erfasst wird.

Es ist auch erwähnenswert, dass die Reihenfolge wichtig ist. Umkehren der Reihenfolge wie folgt:

dir nonexistant 2>&1 >output.txt

ist nicht dasselbe und wird Ihnen wahrscheinlich nicht das gewünschte Ergebnis liefern.

In diesem Fall bewirkt "2> & 1", was zuerst gesehen und verarbeitet wird, dass die Ausgabe für "Stream 2" ("Fehlerausgabe") an die Stelle umgeleitet wird, an die "Stream 1" aktuell geleitet wird, und zwar zu diesem Zeitpunkt Moment ist (standardmäßig) der Bildschirm. Und "> Datei" bewirkt, dass die Ausgabe für "Stream 1" ("Standardausgabe") in der Datei erfasst wird. Das Endergebnis ist, dass die Ausgabe des Befehls ("Stream 1") in der Datei erfasst wird, die Fehlerausgabe ("Stream 2") jedoch weiterhin auf dem Bildschirm angezeigt wird (nicht in der Datei).

Kevin Fegan
quelle
Es stellte sich heraus, dass dies foo.exe>"c:\test.txt"tatsächlich funktionierte, aber es gab einen Fehler, dass das Programm abstürzte (die Ausgabe war jedoch immer noch da). Ihr Vorschlag machte es jedoch noch besser, als 2>&1die Crash-Beschwerde verschwand. Möchten Sie näher erläutern, was es tut? Nochmals vielen Dank für eine tolle Antwort.
pzkpfw
@ bigbadonk420 - Ich habe meine Antwort aktualisiert und Informationen zur Verwendung von hinzugefügt 2>&1. Wenn Sie Ihre Datei "c: \ test.txt" untersuchen, werden Sie höchstwahrscheinlich feststellen, dass die " Absturzbeschwerde" in die Datei geschrieben wurde. 2>&1Sollte das Programm nicht zum Absturz bringen oder verhindern, werden lediglich die Fehlermeldungen erfasst und nicht angezeigt.
Kevin Fegan
1
Aus irgendeinem Grund schon.
pzkpfw
1
@ bigbadonk420 - 'for some reason it does'Inwiefern ist die Umleitung davon betroffen? Wollen Sie damit sagen 2>&1, dass der Fehler nicht auftritt , wenn Sie einschließlich umleiten ? Welche Fehlermeldung wird angezeigt, wenn der Fehler auftritt?
Kevin Fegan
1
Wenn 2>&1es nicht enthalten ist, stürzt das Programm ab und ich erhalte das Standard-Windows-Dialogfeld "Dieses Programm reagiert nicht mehr". Wenn ich es einbinde, tut es das nicht. Keine Ahnung warum. In beiden Fällen wird jedoch eine Ausgabe generiert.
pzkpfw