Escribir la salida del comando en cmd de Windows en un archivo (con un giro)

9

Así que estoy tratando de ejecutar foo.exe, pero no quiero la salida al terminal sino a un archivo. Correr foo.exe > foo.txtdebería lograr esto para mí, pero no lo es. Cuando ejecuto el archivo exe, obtengo el resultado. El exe está funcionando bien en otras palabras. Sin embargo, cuando intento enviar la salida a un archivo, lo único que obtengo es esto:

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

Esto solo aparece cuando intento enviarlo a un archivo. Pensando que podría ser la ruta (que es c:\Program Files (x86)\y así sucesivamente) la que se malinterpreta, intenté especificar el archivo de salida de la siguiente manera: foo.exe > c:\test.txtpero aún así no me alegro.

Entonces, aparte de afirmar que el binario que estoy tratando de ejecutar está mal escrito, ¿hay algo que pueda hacer para remediar esto? Tenga en cuenta que obtengo resultados válidos cuando simplemente ejecuto el exe, simplemente no se imprime bien en un archivo. Obviamente, la salida está ahí, la pregunta es si hay alguna forma de atraparla.

pzkpfw
fuente
¿Qué sucede si mueve el programa a un directorio simple (C: \ Simple o incluso C: \) y prueba estas cosas desde allí?
Jan Doggen

Respuestas:

21

No ha mostrado el comando que está utilizando que falla. Si lo muestra en su pregunta, podría ser más fácil encontrar una solución para usted.

Espero que tu comando sea algo como esto:

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

El error que está recibiendo es una pista:

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

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

Esto suele suceder cuando intenta redirigir a un archivo utilizando un en |lugar de un >.

Segundo:
'c:/Program' ...

Al especificar un nombre de archivo (o ruta) que contiene espacios, debe rodearlo con comillas dobles ( "..."). Esto se debe a que cuando el sistema operativo es determinar el archivo para redirigir a, dejará de buscar el nombre del archivo cuando encuentra un espacio sin comillas: "c:/Program".

Prueba esto:

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



Si lo anterior no funciona para capturar la salida del foo.exearchivo de texto, entonces hay otra posibilidad ...

Si el programa foo.exeestá escribiendo su salida en STDERRlugar de STDOUT, la salida de foo.exeno se capturará utilizando una redirección simple con una sola >. Tendría que hacerlo así:

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



Editar:

Aquí hay una explicación de la redirección de archivos y la 2>&1notación.

Cuando un programa escribe en el terminal, puede escribir en uno de dos Streams.

  1. Flujo 1 se conoce como STDOUTo estándar-salida . Por lo general, los programas escriben su salida "Normal" en la secuencia 1.

  2. La secuencia 2 se conoce como STDERRo error estándar . Normalmente, los programas escriben su salida "Error" (mensajes de error y advertencia) en la transmisión 2.

El programador determina si un programa escribe una salida particular STDOUTo STDERRcómo lo escribió el programa. Algunos programas están escritos para enviar toda la salida (salida normal y errores) a STDOUT.

Cuando se ejecuta un programa sin redireccionamiento de salida, toda la salida normal y de error se envía a la pantalla del terminal sin distinción entre lo que se STDOUTemite o se STDERRemite.

Cuando haces una redirección "normal" con un sencillo >como este:

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

no especifica qué secuencia se redirige al archivo, por lo que se supone la secuencia 1.

Es lo mismo que si lo escribieras así:

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

Esto le dice al intérprete de comandos ( cmd.exe) que capture la salida del programa para STDOUT(Secuencia 1) al nombre de archivo especificado. El 1en 1>se refiere a la corriente 1.

En este caso, todo el programa normal se captura en el archivo, pero si el programa escribe en STDERR(Stream 2), esa salida no se capturará y se mostrará en la pantalla. Esta es generalmente la forma "deseada" de hacerlo, de modo que mientras captura la salida normal del programa, puede ver en la pantalla si se produce un error.

Si desea capturar la salida "Normal" en un archivo y la salida "Error" en un archivo diferente, puede hacerlo así:

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

Si desea que la salida "Normal" y la salida "Error" se capturen en el mismo archivo, puede especificarlo así:

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

Esto es básicamente una forma "abreviada" de especificarlo y significa redirigir la secuencia 1 al archivo especificado, y también redirigir la secuencia 2 al mismo "lugar" (archivo) que la secuencia 1.


Editar:

Pacerier preguntó:

¿Hay alguna diferencia entre foo.exe> ​​"c: \ output.txt" 2> & 1 y foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt"? ¿Son idénticos?

Respuesta corta: pensarías que son idénticos, pero no. Ellos son diferentes.

Con el uso de la redirección >"filename.ext", 1>"filename.ext"o 2>"filename.ext", la >causa que la salida se pueda grabar en un nuevo archivo llamado "filename.ext". Si el archivo "filename.ext" ya existe, se eliminará primero.

Entonces, usando:

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

provoca un "conflicto" en el que ambas redirecciones intentan escribir en el mismo archivo y ambas intentan eliminar el archivo si ya existe. Esto probablemente causará un comportamiento no deseado. En general, una u otra, o ambas, de las salidas NO se capturarán por completo o de manera predecible.

El resultado real dependerá del sistema operativo y la versión, y también puede depender del comando que se ejecute. Lo que probablemente sucederá es:

1 La salida enviada a una de las redirecciones se capturará o se capturará parcialmente, y la salida enviada a otra redirección se perderá. 2 El sistema operativo se quejará del comando y ninguna de las salidas se capturará (completamente). 3 Comportamiento indefinido, indeseable, impredecible e inesperado.

En Windows 7 y probablemente en Windows Vista / 8/10, y posiblemente en Windows XP, el sistema operativo se quejará del comando y el comando será cancelado.

Por ejemplo (Windows 7): Tengo una carpeta llamada: "C:\Temp\emptyfolder"y un archivo llamado "archivo no existente" no existe allí.

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>

En este caso, usando una redirección ( >output.txt), la salida del dircomando se captura en el archivo: output.txty el mensaje de error File Not Foundse muestra en la pantalla ... este es el comportamiento esperado.

Ahora, usando ambas redirecciones ("> archivo" Y "2> archivo"):

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>

En este caso, el sistema operativo se quejó de que el archivo (outout) ya está en uso. Y el archivo "output.txt" termina vacío (0 bytes), y se perdió la salida para ambas redirecciones.

Ahora, por último, usando ambas redirecciones ("> archivo" Y "2> y 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>

En este caso, "> archivo" hace que la salida de la "secuencia 1" ("salida estándar") se capture en el archivo. Y "2> & 1" hace que la salida de "secuencia 2" ("salida de error") se envíe a través de la "secuencia 1" ya redirigida, y que también se capture en el (mismo) archivo.

También vale la pena señalar que el orden es importante. Invertir el orden de esta manera:

dir nonexistant 2>&1 >output.txt

no es lo mismo y probablemente no le dará el resultado deseado.

En este caso, "2> & 1", que se ve y se procesa primero, hace que la salida para "secuencia 2" ("salida de error") se redirija al lugar al que se dirige actualmente "secuencia 1", que en ese momento momento, es (por defecto), la pantalla. Y "> archivo" hace que la salida de "flujo 1" ("salida estándar") se capture en el archivo. El resultado final es que la salida del comando ("secuencia 1") se capturará en el archivo, pero la salida de error ("secuencia 2") seguirá yendo a la pantalla (no al archivo).

Kevin Fegan
fuente
Resulta que foo.exe>"c:\test.txt"realmente funcionó, pero arrojó un error de que el programa se bloqueó (aunque la salida todavía estaba allí). Sin embargo, su sugerencia lo hizo aún mejor ya que 2>&1desapareció la queja de bloqueo. ¿Te importaría elaborar lo que hace? Gracias de nuevo por una gran respuesta.
pzkpfw
@ bigbadonk420: actualicé mi respuesta para incluir información sobre el uso de 2>&1. Si examina su archivo "c: \ test.txt", lo más probable es que vea que la "queja de bloqueo" se escribió en el archivo. 2>&1no debería causar o evitar que el programa se bloquee, solo hace que los mensajes de error se capturen en lugar de mostrarse.
Kevin Fegan
1
Bueno, por alguna razón lo hace.
pzkpfw
1
@ bigbadonk420: 'for some reason it does'¿de qué manera se ve afectado por la redirección? ¿Está diciendo que cuando redirige incluido 2>&1, que el error no ocurre? ¿Qué mensaje de error ves cuando ocurre el error?
Kevin Fegan
1
Cuando 2>&1no está incluido, el programa se bloquea y aparece el cuadro de diálogo estándar de Windows "este programa ha dejado de responder". Cuando lo incluyo, no lo hace. No tengo idea de por qué. Sin embargo, la salida se genera en ambos casos.
pzkpfw