Écriture de la sortie de commande dans Windows cmd dans un fichier (avec une torsion)

9

J'essaie donc de courir foo.exe, mais je ne veux pas la sortie vers le terminal mais dans un fichier. La course foo.exe > foo.txtdevrait accomplir cela pour moi, mais ce n'est pas le cas. Lorsque j'exécute le fichier exe, j'obtiens la sortie. L'exe fonctionne bien en d'autres termes. Cependant, lorsque j'essaie d'envoyer la sortie dans un fichier, la seule chose que j'obtiens est la suivante:

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

Cela n'apparaît que lorsque j'essaie de l'envoyer dans un fichier. Pensant que ce pourrait être le chemin (qui est c:\Program Files (x86)\et ainsi de suite) qui est mal interprété, j'ai essayé de spécifier le fichier de sortie comme ceci:, foo.exe > c:\test.txtmais toujours pas de joie.

Donc, à part déclarer que le binaire que j'essaie d'exécuter est mal écrit, puis-je faire quelque chose pour y remédier? Gardez à l'esprit que j'obtiens une sortie valide lorsque je lance simplement l'exe, cela ne s'imprimera pas bien dans un fichier. Évidemment, la sortie est là, la question est de savoir s'il existe un moyen de l'attraper.

pzkpfw
la source
Que se passe-t-il si vous déplacez le programme vers un répertoire simple (C: \ Simple ou même C: \) et essayez ces choses à partir de là?
Jan Doggen

Réponses:

21

Vous n'avez pas montré la commande que vous utilisez qui échoue. Si vous le montrez dans votre question, il pourrait être plus facile de trouver une solution pour vous.

Je suppose que votre commande est quelque chose comme ceci:

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

L'erreur que vous recevez est en quelque sorte un indice:

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

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

Cela se produit généralement lorsque vous essayez de rediriger vers un fichier à l'aide d'un |au lieu d'un >.

Seconde:
'c:/Program' ...

Lorsque vous spécifiez un nom de fichier (ou chemin d'accès) contenant des espaces, vous devez l'entourer de guillemets doubles ( "..."). En effet , lorsque le système d' exploitation est de déterminer le fichier de redirection, il cessera de chercher le nom de fichier quand il rencontre un espace non protégé: "c:/Program".

Essaye ça:

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



Si ce qui précède ne fonctionne pas pour capturer la sortie de foo.exedans le fichier texte, il existe une autre possibilité ...

Si le programme foo.exeécrit sa sortie dans au STDERRlieu de STDOUT, la sortie de foo.exene sera pas capturée en utilisant une redirection simple avec un seul >. Vous devez le faire comme ceci:

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



Éditer:

Voici une explication de la redirection de fichiers et de la 2>&1notation.

Lorsqu'un programme écrit sur le terminal, il peut écrire sur l'un des deux Streams.

  1. Le flux 1 est appelé STDOUTou sortie standard . En règle générale, les programmes écrivent leur sortie "Normal" dans le flux 1.

  2. Le flux 2 est appelé STDERRou erreur standard . En règle générale, les programmes écrivent leur sortie "Erreur" (messages d'erreur et d'avertissement) dans le flux 2.

Si un programme écrit une sortie particulière STDOUTou STDERRest déterminé par le programmeur et comment il a écrit le programme. Certains programmes sont écrits pour envoyer toutes les sorties (sortie normale et erreurs) vers STDOUT.

Lorsqu'un programme est exécuté sans redirection de sortie, toutes les sorties normales et erreurs sont envoyées à l'écran du terminal sans aucune distinction entre ce qui est STDOUTsorti ou STDERRsorti.

Lorsque vous effectuez une redirection "normale" avec un single >comme celui-ci:

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

vous ne spécifiez pas quel Stream est redirigé vers le fichier, donc Stream 1 est supposé.

C'est la même chose que si vous l'avez tapé comme ceci:

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

Cela indique à l'interpréteur de commandes ( cmd.exe) de capturer la sortie du programme pour STDOUT(Stream 1) avec le nom de fichier spécifié. L' 1entrée 1>fait référence au flux 1.

Dans ce cas, tout le programme normal est capturé dans le fichier, mais si le programme écrit dans STDERR(Stream 2), cette sortie ne sera pas capturée et sera affichée à l'écran. Il s'agit généralement de la méthode "souhaitée" pour que, pendant que vous capturez la sortie normale du programme, vous puissiez voir à l'écran si une erreur se produit.

Si vous voulez capturer la sortie "Normal" dans un fichier et la sortie "Erreur" dans un autre fichier, vous pouvez le faire comme ceci:

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

Si vous voulez que la sortie "Normal" et la sortie "Erreur" soient capturées dans le même fichier, vous pouvez le spécifier comme ceci:

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

Il s'agit essentiellement d'une manière "abrégée" de le spécifier et cela signifie rediriger le flux 1 vers le fichier spécifié, et également rediriger le flux 2 vers le même "endroit" (fichier) que le flux 1.


Éditer:

Pacerier a demandé:

Existe-t-il une différence entre foo.exe> ​​"c: \ output.txt" 2> & 1 et foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt"? Sont-ils identiques?

Réponse courte: on pourrait penser qu'ils sont identiques, mais non. Ils sont différents.

Avec l' aide de redirection >"filename.ext", 1>"filename.ext"ou 2>"filename.ext", le >fait que la sortie à écrire dans un nouveau fichier nommé « filename.ext ». Si le fichier "filename.ext" existe déjà, il sera d'abord supprimé.

Donc, en utilisant:

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

provoque un «conflit» où les deux redirections tentent d'écrire dans le même fichier et les deux tentent de supprimer le fichier s'il existe déjà. Cela entraînera probablement un comportement indésirable. Généralement, l'une ou l'autre, ou les deux, des sorties ne seront PAS capturées de manière complète ou prévisible.

Le résultat réel dépendra du système d'exploitation et de la version, et peut également dépendre de la commande en cours d'exécution. Ce qui se produira probablement, c'est:

1 La sortie envoyée à l'une des redirections sera capturée ou partiellement capturée, et la sortie envoyée à l'autre redirection sera perdue. 2 Le système d'exploitation se plaindra de la commande et aucune des sorties ne sera capturée (entièrement). 3 Comportement non défini, indésirable, imprévisible et inattendu.

Sur Windows 7 et probablement sur Windows Vista / 8/10, et peut-être sur Windows XP, le système d'exploitation se plaindra de la commande et la commande sera annulée.

Par exemple (Windows 7): J'ai un dossier nommé: "C:\Temp\emptyfolder"et un fichier nommé "fichier non existant" n'existe pas là.

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>

Dans ce cas, en utilisant une redirection ( >output.txt), la sortie de la dircommande est capturée dans le fichier:, output.txtet le message d'erreur File Not Foundest affiché à l'écran ... c'est le comportement attendu.

Maintenant, en utilisant les deux redirections ("> fichier" ET "2> fichier"):

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>

Dans ce cas, le système d'exploitation s'est plaint que le fichier (outout) était déjà utilisé. Et le fichier "output.txt" finit vide (0 octet), et la sortie pour les deux redirections a été perdue.

Maintenant, enfin, en utilisant les deux redirections ("> fichier" ET "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>

Dans ce cas, "> fichier" provoque la capture du fichier "flux 1" ("sortie standard") dans le fichier. Et "2> & 1" fait que la sortie du "flux 2" ("sortie d'erreur") est envoyée via le "flux 1" déjà redirigé et est également capturée dans le (même) fichier.

Il convient également de noter que la commande est importante. Inverser l'ordre comme ceci:

dir nonexistant 2>&1 >output.txt

n'est pas le même et ne vous donnera probablement pas le résultat souhaité.

Dans ce cas, "2> & 1", qui est vu et précédé en premier, entraîne la redirection de la sortie du "flux 2" ("sortie d'erreur") vers l'endroit où le "flux 1" est actuellement dirigé, qui à ce moment-là moment, est (par défaut), l'écran. Et "> fichier" entraîne la capture du fichier "flux 1" ("sortie standard") dans le fichier. Le résultat final est que la sortie de la commande ("flux 1") sera capturée dans le fichier, mais la sortie d'erreur ("flux 2"), ira toujours à l'écran (pas dans le fichier).

Kevin Fegan
la source
Il s'avère que cela a foo.exe>"c:\test.txt"réellement fonctionné, mais cela a provoqué une erreur de plantage du programme (la sortie était toujours là cependant). Cependant, votre suggestion l'a rendu encore meilleur, car la 2>&1plainte pour crash a disparu. Voulez-vous élaborer sur ce qu'il fait? Merci encore pour une excellente réponse.
pzkpfw
@ bigbadonk420 - J'ai mis à jour ma réponse pour inclure des informations sur l'utilisation de 2>&1. Si vous examinez votre fichier "c: \ test.txt", vous verrez très probablement que la "plainte de plantage" a été écrite dans le fichier. 2>&1ne doit pas provoquer ou empêcher le programme de planter, cela provoque simplement la capture des messages d'erreur plutôt que leur affichage.
Kevin Fegan
1
Eh bien, pour une raison quelconque, c'est le cas.
pzkpfw
1
@ bigbadonk420 - 'for some reason it does'de quelle manière est-il affecté par la redirection? Voulez-vous dire que lorsque vous redirigez notamment 2>&1, que l'erreur ne se produit pas? Quel message d'erreur voyez-vous lorsque l'erreur se produit?
Kevin Fegan
1
Lorsque 2>&1n'est pas inclus, le programme se bloque et j'obtiens la boîte de dialogue standard de Windows "ce programme a cessé de répondre". Quand je l'inclus, ce n'est pas le cas. Je ne sais pas pourquoi. La sortie est cependant générée dans les deux cas.
pzkpfw