Rediriger la cmd stdout et stderr de Windows vers un seul fichier

688

J'essaie de rediriger toutes les sorties (stdout + stderr) d'une commande DOS vers un seul fichier:

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

Est-il possible, ou devrais-je simplement rediriger vers deux fichiers distincts?

ripper234
la source
14
TechNet: utilisation des opérateurs de redirection de commandes (répond mieux à cette question qu'à toutes les réponses ici).
Martin Prikryl
1
2> & 1 car il ne peut pas rouvrir le même fichier
Luke

Réponses:

1090

Tu veux:

dir > a.txt 2>&1

La syntaxe 2>&1redirigera 2(stderr) vers 1(stdout). Vous pouvez également masquer les messages en les redirigeant vers NUL, plus d'explications et d'exemples sur MSDN .

Anders Lindahl
la source
32
merci pour cela, je ne savais pas que cette syntaxe de shell unix fonctionne aussi pour DOS!
chaindriver
20
c'est super pour cacher toutes les sorties .. net stop w3svc >NUL 2>&1.. merci!
wasatchwizard
3
@wasatchwizard Ithink J'ai eu des problèmes avec ça, mais> NUL 2> NUL a bien fonctionné
FrinkTheBrave
13
S'il y a un Handle, il ne peut y avoir d'espace entre le Handle (ie 2) et l'opérateur de redirection (ie>). Par conséquent 2> 2.txtfonctionne (ou 2> &1) 2 > 2.txtne fonctionne pas; 2 > &1ne fait pas.
The Red Pea
9
J'adore tellement. "Ugh, ce petit problème ponctuel va prendre environ une heure". Il m'a fallu plus de temps pour taper ce commentaire que pour trouver cette réponse.
Brandon
195

La réponse d'Anders Lindahl est correcte, mais il convient de noter que si vous redirigez stdout vers un fichier et que vous souhaitez également rediriger stderr, vous DEVEZ vous assurer que cela 2>&1est spécifié APRÈS la 1>redirection, sinon cela ne fonctionnera pas.

REM *** WARNING: THIS WILL NOT REDIRECT STDERR TO STDOUT ****
dir 2>&1 > a.txt
DelboyJay
la source
10
APRÈS c'est ce qui m'a coûté des heures pour comprendre ce qui ne va pas DelboyJay! Je vous remercie!
Nam G VU
4
Est-il expliqué quelque part pourquoi mettre 2> & 1 avant 1> n'obtiendra pas l'effet escompté? Je soupçonne fortement que cela a à voir avec la façon dont "cmd" analyse les commandes qui donne deux significations différentes selon l'ordre dans lequel vous spécifiez la redirection. Mais les règles sémantiques sont-elles documentées n'importe où parce que je pense que cela vaut la peine d'apprendre car cela pourrait perdre des heures.
igbgotiz
12
@igbgotiz 2> & 1 signifie 'rediriger le flux 2 vers le flux 1'. Vous devez donc d'abord configurer le flux 1
FrinkTheBrave
3
@FrinkTheBrave mais le flux 1 est une sortie standard (par exemple console) s'il n'est pas spécifié explicitement. Cela ne l'explique toujours pas à mon humble avis.
MarioDS
1
@MDeSchaepmeester, si vous le faites dir 2>&1 > a.txt , vous redirigez d'abord ( >) le flux 2 (stderr) vers le flux 1 (stdout). Ensuite, une fois les deux déjà réunis, vous redirigez stdout ( >sans spécificateur) vers le fichier. Si vous voulez que stderr aille ailleurs, vous ne pouvez pas le rejoindre d'abord avec stdout.
cp.engr
80

Informations générales de MSKB

Bien que la réponse acceptée à cette question soit correcte, cela ne fait vraiment pas grand-chose pour expliquer pourquoi cela fonctionne, et puisque la syntaxe n'est pas immédiatement claire, j'ai fait un rapide google pour savoir ce qui se passait réellement. Dans l'espoir que ces informations soient utiles aux autres, je les publie ici.

Tiré de MS Support KB 110930 .


À partir de MSKB110930

Redirection des messages d'erreur à partir de l'invite de commandes: STDERR / STDOUT

Sommaire

Lors de la redirection de la sortie d'une application à l'aide du symbole «>», les messages d'erreur s'impriment toujours à l'écran. En effet, les messages d'erreur sont souvent envoyés au flux d'erreur standard au lieu du flux de sortie standard.

La sortie d'une application ou d'une commande de console (invite de commande) est souvent envoyée à deux flux distincts. La sortie régulière est envoyée à la sortie standard (STDOUT) et les messages d'erreur sont envoyés à l'erreur standard (STDERR). Lorsque vous redirigez la sortie de la console à l'aide du symbole ">", vous redirigez uniquement STDOUT. Afin de rediriger STDERR, vous devez spécifier «2>» pour le symbole de redirection. Ceci sélectionne le deuxième flux de sortie qui est STDERR.

Exemple

La commande dir file.xxx (où file.xxxn'existe pas) affichera la sortie suivante:

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

File Not Found

Si vous redirigez la sortie vers le NUL appareil en utilisant dir file.xxx > nul, vous verrez toujours la partie message d'erreur de la sortie, comme ceci:

File Not Found

Pour rediriger (uniquement) le message d'erreur vers NUL , utilisez la commande suivante:

dir file.xxx 2> nul

Ou, vous pouvez rediriger la sortie vers un endroit et les erreurs vers un autre.

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

Vous pouvez imprimer les erreurs et la sortie standard dans un seul fichier en utilisant la commande "& 1" pour rediriger la sortie de STDERR vers STDOUT, puis en envoyant la sortie de STDOUT vers un fichier:

dir file.xxx 1> output.msg 2>&1
StormeHawke
la source
29

Pour ajouter stdout et stderr au fichier journal général d'un script:

dir >> a.txt 2>&1
Henk Wiersema
la source
9
Le >>ajoute au fichier où le >remplace le fichier.
delliottg
13

Correct, le descripteur de fichier 1 pour le processus est STDOUT, redirigé par le 1>ou par >(1 peut être omis, par convention, l'interpréteur de commandes [cmd.exe] sait gérer cela). Le descripteur de fichier 2 est STDERR, redirigé par 2>.

Notez que si vous les utilisez pour créer des fichiers journaux, à moins que vous n'envoyiez la sortie vers des fichiers journaux _uniquely_named_ (par exemple, horodatés), alors si vous exécutez le même processus deux fois, la redirection sera écrasée ( remplacer) le fichier journal précédent.

le >> (pour STDOUT ou STDERR) APPENDRA PAS REMPLACER le fichier. Ainsi, vous obtenez un fichier journal cumulatif, montrant les résultats de toutes les exécutions du processus - généralement plus utiles.

Bonne route...

Max Vitesse
la source
2

Il n'y a cependant aucune garantie que la sortie de SDTOUTet STDERRsont entrelacées ligne par ligne en temps opportun, en utilisant la POSIXsyntaxe de fusion de redirection.

Si une application utilise une sortie mise en mémoire tampon, il peut arriver que le texte d'un flux soit inséré dans l'autre à une limite de mémoire tampon, qui peut apparaître au milieu d'une ligne de texte.

Un enregistreur de sortie de console dédié (c'est-à-dire "StdOut/StdErr Logger"par'LoRd MuldeR' ) peut être plus fiable pour une telle tâche.

Voir: Projets OpenSource de MuldeR

LigH
la source
0

Dans un fichier batch (Windows 7 et supérieur), j'ai trouvé cette méthode la plus fiable

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

De toute évidence, utilisez les commandes que vous voulez et la sortie sera dirigée vers le fichier texte. L'utilisation de cette méthode est fiable TOUTEFOIS, il n'y a AUCUNE sortie à l'écran.

PanamaPHat
la source
(essentiellement la même réponse donnée quelques fois il y a quelques années.) Vous pouvez forcer la sortie à l' écran avec >con echo This goes to screenégalement utile pour la saisie de l' utilisateur >con set /p "var="Input: "Remarque: ces lignes seront uniquement apparaître à l' écran et ne pas être redirigé vers le fichier.
Stephan