Scrivere l'output del comando in Windows cmd in un file (con una svolta)


9

Quindi sto cercando di eseguire foo.exe, ma non voglio l'output sul terminale ma in un file. Correre foo.exe > foo.txtdovrebbe realizzare questo per me, ma non lo è. Quando eseguo il file exe, ottengo l'output. L'exe funziona bene in altre parole. Tuttavia, quando provo a inviare l'output a un file, l'unica cosa che ottengo è questa:

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

Questo viene visualizzato solo quando provo a inviarlo a un file. Pensando che potrebbe essere il percorso (che è c:\Program Files (x86)\e così via) a essere interpretato erroneamente, ho provato a specificare il file di output in questo modo:, foo.exe > c:\test.txtma ancora nessuna gioia.

Quindi, a parte affermare che il binario che sto cercando di eseguire è scritto male, c'è qualcosa che posso fare per rimediare? Tieni presente che ottengo un output valido quando eseguo semplicemente l'exe, semplicemente non verrà stampato correttamente su un file. Ovviamente l'output è lì, la domanda è se c'è un modo per catturarlo.


Cosa succede se sposti il ​​programma in una semplice directory (C: \ Simple o anche C: \) e provi queste cose da lì?
Jan Doggen,

Risposte:


21

Non hai mostrato il comando che stai utilizzando che non riesce. Se lo mostri nella tua domanda, potrebbe essere più facile trovare una soluzione per te.

Mi aspetto che il tuo comando sia qualcosa del genere:

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

L'errore che stai ricevendo è in qualche modo un indizio:

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

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

Ciò si verifica in genere quando si tenta di reindirizzare a un file utilizzando un |anziché un >.

Secondo:
'c:/Program' ...

Quando si specifica un nome file (o percorso) che contiene spazi, è necessario racchiuderlo tra virgolette ( "..."). Questo perché quando il sistema operativo è determinare il file per reindirizzare a, si fermerà alla ricerca del nome del file quando incontra uno spazio non quotate: "c:/Program".

Prova questo:

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



Se quanto sopra non funziona per catturare l'output dal foo.exefile di testo, allora c'è un'altra possibilità ...

Se il programma foo.exesta scrivendo il proprio output STDERRanziché invece STDOUT, l'output di foo.exenon verrà catturato utilizzando il reindirizzamento semplice con un singolo >. Dovresti farlo in questo modo:

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



Modificare:

Ecco una spiegazione del reindirizzamento dei file e della 2>&1notazione.

Quando un programma scrive sul terminale, può scrivere su uno dei due Streams.

  1. Streaming 1 è indicato come STDOUTo standard-Output . In genere, i programmi scrivono il loro output "Normal" nello stream 1.

  2. Stream 2 viene indicato come STDERRo standard-Error . In genere, i programmi scrivono l' output "Errore" (messaggi di errore e di avviso) nello stream 2.

Se un programma scrive un determinato output nel STDOUTo STDERRè determinato dal programmatore e come hanno scritto il programma. Alcuni programmi sono scritti per inviare tutto l'output (output normale ed errori) a STDOUT.

Quando un programma viene eseguito senza reindirizzamento dell'output, tutto l'output normale e di errore viene inviato alla schermata del terminale senza alcuna distinzione tra STDOUToutput o STDERRoutput.

Quando esegui il reindirizzamento "normale" con un singolo >come questo:

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

non stai specificando quale Stream viene reindirizzato al file, quindi si presume Stream 1.

È lo stesso che se lo scrivessi così:

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

Questo dice all'interprete dei comandi ( cmd.exe) di catturare l'output del programma per STDOUT(Stream 1) nel nome file specificato. La 1in 1>riferisce a stream 1.

In questo caso, tutto il programma normale viene acquisito nel file, ma se il programma scrive su STDERR(Stream 2), quell'output non verrà acquisito e verrà visualizzato sullo schermo. Questo è generalmente il modo "desiderato" per farlo in modo che mentre si sta catturando il normale output del programma, si possa vedere sullo schermo se si verifica un errore.

Se vuoi catturare l'output "Normale" su un file e l'output "Errore" su un altro file puoi farlo in questo modo:

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

Se si desidera che l'output "Normale" e l'output "Errore" vengano acquisiti nello stesso file, è possibile specificarlo in questo modo:

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

Questo è fondamentalmente un modo "abbreviato" di specificarlo e significa reindirizzare Stream 1 al file specificato e reindirizzare Stream 2 allo stesso "posto" (file) dello Stream 1.


Modificare:

Pacerier ha chiesto:

C'è qualche differenza tra foo.exe> ​​"c: \ output.txt" 2> & 1 e foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt"? Sono identici?

Risposta breve: si potrebbe pensare che siano identici, ma no. Sono diversi.

Con il reindirizzamento usando >"filename.ext", 1>"filename.ext"o 2>"filename.ext", la >causa l'uscita da scrivere un nuovo file denominato "filename.ext". Se il file "nomefile.ext" esiste già, verrà prima eliminato.

Quindi, usando:

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

provoca un "conflitto" in cui entrambi i reindirizzamenti stanno provando a scrivere nello stesso file ed entrambi stanno cercando di eliminare il file se esiste già. Ciò probabilmente causerà comportamenti indesiderati. Generalmente, l'una o l'altra o entrambe le uscite NON verranno catturate in modo completo o prevedibile.

Il risultato effettivo dipenderà dal sistema operativo e dalla versione e potrebbe anche dipendere dal comando eseguito. Ciò che probabilmente accadrà è:

1 L'output inviato a uno dei reindirizzamenti verrà acquisito o parzialmente acquisito e l'output inviato ad altri reindirizzamenti andrà perso. 2 Il sistema operativo si lamenterà del comando e nessuno degli output verrà acquisito (completamente). 3 Comportamento indefinito, indesiderato, imprevedibile, imprevisto.

Su Windows 7 e probabilmente su Windows Vista / 8/10, e possibilmente su Windows XP, il sistema operativo si lamenterà del comando e il comando verrà annullato.

Ad esempio (Windows 7): ho una cartella denominata: "C:\Temp\emptyfolder"e non esiste un file chiamato "file inesistente".

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 questo caso, usando un reindirizzamento ( >output.txt), l'output del dircomando viene catturato dal file:, output.txte il messaggio di errore File Not Foundviene mostrato sullo schermo ... questo è il comportamento previsto.

Ora, usando entrambi i reindirizzamenti ("> file" AND "2> file"):

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 questo caso, il sistema operativo si è lamentato del fatto che il file (outout) è già in uso. E il file "output.txt" finisce vuoto (0 byte) e l'output per entrambi i reindirizzamenti è andato perso.

Ora, infine, usando entrambi i reindirizzamenti ("> file" AND "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 questo caso, "> file" fa sì che l'output di "stream 1" ("output standard") venga acquisito nel file. E "2> & 1" fa sì che l'output di "stream 2" ("output di errore") sia inviato attraverso lo "stream 1" già reindirizzato e sia catturato anche nello (stesso) file.

Vale anche la pena notare che l'ordine è importante. Invertire l'ordine in questo modo:

dir nonexistant 2>&1 >output.txt

non è lo stesso e probabilmente non ti darà il risultato desiderato.

In questo caso, "2> & 1", che viene visualizzato e preceduto per primo, fa sì che l'output per "stream 2" ("output dell'errore") venga reindirizzato al punto in cui è attualmente diretto "stream 1", che a quel punto momento, è (per impostazione predefinita), lo schermo. E "> file" fa sì che l'output di "stream 1" ("output standard") venga acquisito nel file. Il risultato finale è che l'output del comando ("stream 1") verrà acquisito nel file, ma l'output dell'errore ("stream 2") andrà comunque alla schermata (non al file).


Si è scoperto che in foo.exe>"c:\test.txt"realtà ha funzionato, ma ha generato un errore nel crash del programma (l'output era ancora lì). Tuttavia, il tuo suggerimento lo ha reso ancora migliore in quanto il 2>&1reclamo per crash è stato eliminato. Ti interessa approfondire cosa fa? Grazie ancora per un'ottima risposta.
pzkpfw,

@ bigbadonk420 - Ho aggiornato la mia risposta per includere informazioni sull'uso di 2>&1. Se esamini il tuo file "c: \ test.txt", molto probabilmente vedrai che la "denuncia di arresto anomalo" è stata scritta nel file. 2>&1non dovrebbe causare o impedire l'arresto anomalo del programma, causa solo l'acquisizione dei messaggi di errore anziché la loro visualizzazione.
Kevin Fegan,

1
Bene, per qualche motivo lo fa.
pzkpfw,

1
@ bigbadonk420 - 'for some reason it does'in che modo è influenzato dal reindirizzamento? Stai dicendo che quando reindirizzi incluso 2>&1, che l'errore non si verifica? Quale messaggio di errore viene visualizzato quando si verifica l'errore?
Kevin Fegan,

1
Quando 2>&1non è incluso, il programma si arresta in modo anomalo e viene visualizzata la finestra di dialogo "questo programma ha smesso di rispondere". Quando lo includo, non lo fa. Non ho idea del perché. L'output è generato in entrambi i casi.
pzkpfw,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.