Reindirizza Windows cmd stdout e stderr su un singolo file


688

Sto cercando di reindirizzare tutto l'output (stdout + stderr) di un comando DOS su un singolo file:

C:\>dir 1> a.txt 2> a.txt
The process cannot access the file because it is being used by another process.

È possibile o devo semplicemente reindirizzare a due file separati?


15
TechNet: utilizzo degli operatori di reindirizzamento dei comandi (risponde meglio di una qualsiasi delle risposte qui).
Martin Prikryl,

1
2> & 1 in quanto non è possibile riaprire lo stesso file
Luca

Risposte:


1090

Tu vuoi:

dir > a.txt 2>&1

La sintassi 2>&1reindirizzerà 2(stderr) a 1(stdout). Puoi anche nascondere i messaggi reindirizzando a NUL, ulteriori spiegazioni ed esempi su MSDN .


32
grazie per questo, non sapevo che questa sintassi della shell unix funziona anche per DOS!
chaindriver

20
questo è ottimo per nascondere tutto l'output .. net stop w3svc >NUL 2>&1.. grazie!
wasatchwizard

3
@wasatchwizard Pensavo di avere problemi con questo, ma> NUL 2> NUL ha funzionato bene
FrinkTheBrave

13
Se è presente una maniglia, non può esserci spazio tra la maniglia (ovvero 2) e l'operatore di reindirizzamento (ovvero>). Pertanto 2> 2.txtfunziona (o 2> &1) 2 > 2.txtno; 2 > &1non.
The Red Pea,

9
Adoro così tanto. "Ugh, questo piccolo problema una tantum ci vorrà circa un'ora". Mi ci è voluto più tempo per scrivere questo commento che per trovare questa risposta.
Brandon,

195

La risposta di Anders Lindahl è corretta, ma va notato che se stai reindirizzando stdout su un file e vuoi reindirizzare anche stderr, DEVI assicurarti che 2>&1sia specificato DOPO il 1>reindirizzamento, altrimenti non funzionerà.

REM *** WARNING: THIS WILL NOT REDIRECT STDERR TO STDOUT ****
dir 2>&1 > a.txt

10
DOPO che cosa mi è costato ore per capire cosa non va DelboyJay! Grazie!
Nam G VU,

4
È spiegato ovunque perché mettere 2> & 1 prima di 1> non otterrà l'effetto desiderato? Sospetto fortemente che ciò abbia a che fare con il modo in cui "cmd" analizza i comandi che danno due significati diversi a seconda dell'ordine in cui si specifica il reindirizzamento. Ma le regole semantiche sono documentate ovunque perché ritengo che sia qualcosa che vale la pena imparare in quanto potrebbe perdere ore.
igbgotiz,

12
@igbgotiz 2> & 1 significa "reindirizzare lo stream 2 allo stream 1". Quindi devi prima impostare lo stream 1
FrinkTheBrave il

3
@FrinkTheBrave ma lo stream 1 è un output standard (ad es. Console) se non specificato esplicitamente. Questo ancora non lo spiega imho.
MarioDS,

1
@MDeSchaepmeester, se lo fai dir 2>&1 > a.txt, per prima cosa stai reindirizzando ( >) stream 2 (stderr) allo stream 1 (stdout). Quindi, dopo che entrambi sono già stati uniti, stai reindirizzando stdout ( >senza specificatore) al file. Se vuoi che stderr vada da qualche altra parte, non puoi unirti prima a stdout.
cp.engr,

80

Informazioni di background da MSKB

Mentre la risposta accettata a questa domanda è corretta, in realtà non fa molto per spiegare perché funziona e, poiché la sintassi non è immediatamente chiara, ho fatto un rapido google per scoprire cosa stesse realmente accadendo. Nella speranza che queste informazioni siano utili agli altri, le sto pubblicando qui.

Tratto da MS Support KB 110930 .


Da MSKB110930

Reindirizzamento dei messaggi di errore dal prompt dei comandi: STDERR / STDOUT

Sommario

Quando si reindirizza l'output da un'applicazione utilizzando il simbolo '>', i messaggi di errore continuano a essere stampati sullo schermo. Questo perché i messaggi di errore vengono spesso inviati al flusso di errore standard anziché al flusso di uscita standard.

L'output da un'applicazione o un comando della console (prompt dei comandi) viene spesso inviato a due flussi separati. L'uscita normale viene inviata a Uscita standard (STDOUT) e i messaggi di errore vengono inviati a Errore standard (STDERR). Quando si reindirizza l'output della console utilizzando il simbolo ">", si reindirizza solo STDOUT. Per reindirizzare STDERR devi specificare '2>' per il simbolo di reindirizzamento. Questo seleziona il secondo flusso di output che è STDERR.

Esempio

Il comando dir file.xxx(dove file.xxxnon esiste) visualizzerà il seguente output:

Volume in drive F is Candy Cane Volume Serial Number is 34EC-0876

File Not Found

Se reindirizzi l'output al NULdispositivo utilizzando dir file.xxx > nul, vedrai comunque la parte del messaggio di errore dell'output, in questo modo:

File Not Found

Per reindirizzare (solo) il messaggio di errore a NUL, utilizzare il seguente comando:

dir file.xxx 2> nul

In alternativa, è possibile reindirizzare l'output in una posizione e gli errori in un'altra.

dir file.xxx > output.msg 2> output.err

È possibile stampare gli errori e l'output standard su un singolo file utilizzando il comando "& 1" per reindirizzare l'output di STDERR su STDOUT e quindi inviare l'output da STDOUT a un file:

dir file.xxx 1> output.msg 2>&1

29

Per aggiungere lo stdout e lo stderr al file di registro generale di uno script:

dir >> a.txt 2>&1

9
Si >>aggiunge al file in cui >sovrascrive il file.
delliottg,

13

Corretto, l'handle di file 1 per il processo è STDOUT, reindirizzato da 1>o da >(1 può essere omesso, per convenzione, l'interprete dei comandi [cmd.exe] sa gestirlo). L'handle di file 2 è STDERR, reindirizzato da 2>.

Si noti che se si utilizzano questi per creare file di registro, a meno che non si invii l'uscita a file di registro _uniquely_named_ (ad esempio data e ora), quindi se si esegue lo stesso processo due volte, il reindirizzato verrà sovrascritto ( sostituire) il file di registro precedente.

Il >> (sia per STDOUT oppure STDERR) aggiungerà non sostituisce il file. Quindi ottieni un file di registro cumulativo, mostrando i risultati di tutte le esecuzioni del processo, in genere più utili.

Sentieri felici ...


2

Non vi è tuttavia alcuna garanzia che l'output di SDTOUTe STDERRsiano intrecciati riga per riga in ordine tempestivo, utilizzandoPOSIX sintassi di unione di reindirizzamento.

Se un'applicazione utilizza un output bufferizzato, può accadere che il testo di uno stream venga inserito nell'altro in corrispondenza di un limite del buffer, che può apparire nel mezzo di una riga di testo.

Un logger output della console dedicata (cioè l' "StdOut/StdErr Logger"by'LoRd MuldeR' ) può essere più affidabile per tale attività.

Vedi: i progetti OpenSource di MuldeR


0

In un file batch (Windows 7 e versioni successive) ho trovato questo metodo più affidabile

Call :logging >"C:\Temp\NAME_Your_Log_File.txt" 2>&1
:logging
TITLE "Logging Commands"
ECHO "Read this output in your log file"
ECHO ..
Prompt $_
COLOR 0F

Ovviamente, usa qualunque comando tu voglia e l'output verrà indirizzato al file di testo. L'uso di questo metodo è affidabile TUTTAVIA, NON è presente alcun output sullo schermo.


(sostanzialmente la stessa risposta data qualche anno fa). È possibile forzare l'output sullo schermo con >con echo This goes to screenUtile anche per l'input dell'utente >con set /p "var="Input: "Nota: tali righe appariranno solo sullo schermo e non verranno reindirizzate al file.
Stephan,
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.