Redirigir Windows cmd stdout y stderr a un solo archivo

688

Estoy tratando de redirigir toda la salida (stdout + stderr) de un comando de DOS a un solo archivo:

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

¿Es posible, o debería simplemente redirigir a dos archivos separados?

ripper234
fuente
14
TechNet: Uso de operadores de redirección de comandos (responde esto mejor que cualquiera de las respuestas aquí).
Martin Prikryl
1
2> & 1 ya que no puede volver a abrir el mismo archivo
Lucas

Respuestas:

1090

Usted quiere:

dir > a.txt 2>&1

La sintaxis 2>&1redirigirá 2(stderr) a 1(stdout). También puede ocultar mensajes redirigiendo a NUL, más explicaciones y ejemplos en MSDN .

Anders Lindahl
fuente
32
gracias por esto, ¡no sabía que esta sintaxis de shell de Unix también funciona para DOS!
chaindriver
20
esto es genial para ocultar toda la salida ... net stop w3svc >NUL 2>&1¡gracias!
wasatchwizard
3
@wasatchwizard Creo que tuve problemas con eso, pero> NUL 2> NUL funcionó bien
FrinkTheBrave
13
Si hay una manija, no puede haber un espacio entre la manija (es decir, 2) y el operador de redireccionamiento (es decir,>). Por lo tanto 2> 2.txtfunciona (o 2> &1) 2 > 2.txtno; 2 > &1no.
The Red Pea
99
Amo TANTO "Ugh, este pequeño problema único tomará como una hora". Me tomó más tiempo escribir este comentario que encontrar esta respuesta.
Brandon el
195

La respuesta de Anders Lindahl es correcta, pero debe tenerse en cuenta que si está redirigiendo stdout a un archivo y desea redirigir también stderr, DEBE asegurarse de que 2>&1se especifique DESPUÉS de la 1>redirección, de lo contrario no funcionará.

REM *** WARNING: THIS WILL NOT REDIRECT STDERR TO STDOUT ****
dir 2>&1 > a.txt
DelboyJay
fuente
10
¡DESPUÉS es lo que me costó horas descubrir qué sucede DelboyJay! ¡Gracias!
Nam G VU
44
¿Se explica en alguna parte por qué poner 2> y 1 antes de 1> no logrará el efecto deseado? Sospecho firmemente que esto tiene que ver con la forma en que "cmd" analiza los comandos que le dan dos significados diferentes según el orden en que especifique la redirección. Pero las reglas semánticas están documentadas en cualquier lugar porque creo que es algo que vale la pena aprender, ya que podría perder horas.
igbgotiz
12
@igbgotiz 2> & 1 significa 'redirigir la secuencia 2 a la secuencia 1'. Por lo tanto, primero debe configurar la transmisión 1
FrinkTheBrave
3
@FrinkTheBrave pero la secuencia 1 es salida estándar (por ejemplo, consola) si no se especifica explícitamente. Eso todavía no lo explica en mi humilde opinión.
MarioDS
1
@MDeSchaepmeester, si lo hace dir 2>&1 > a.txt, primero está redirigiendo ( >) la secuencia 2 (stderr) a la secuencia 1 (stdout). Luego, después de que ambos ya estén unidos, está redirigiendo stdout ( >sin especificador) al archivo. Si quieres que stderr vaya a otro lado, no puedes unirlo con stdout primero.
cp.engr
80

Información de antecedentes de MSKB

Si bien la respuesta aceptada a esta pregunta es correcta, realmente no hace mucho para explicar por qué funciona, y dado que la sintaxis no está clara de inmediato, hice un rápido google para descubrir qué estaba pasando realmente. Con la esperanza de que esta información sea útil para otros, la publicaré aquí.

Tomado de MS Support KB 110930 .


De MSKB110930

Redirigir mensajes de error desde el símbolo del sistema: STDERR / STDOUT

Resumen

Al redirigir la salida de una aplicación usando el símbolo '>', los mensajes de error aún se imprimen en la pantalla. Esto se debe a que los mensajes de error a menudo se envían a la secuencia de error estándar en lugar de a la secuencia de salida estándar.

La salida de una aplicación de consola (Símbolo del sistema) o un comando a menudo se envía a dos secuencias separadas. La salida regular se envía a Salida estándar (STDOUT) y los mensajes de error se envían a Error estándar (STDERR). Cuando redirige la salida de la consola con el símbolo ">", solo redirige STDOUT. Para redirigir STDERR, debe especificar '2>' para el símbolo de redireccionamiento. Esto selecciona la segunda secuencia de salida que es STDERR.

Ejemplo

El comando dir file.xxx(donde file.xxxno existe) mostrará el siguiente resultado:

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

File Not Found

Si redirige la salida al NULdispositivo usando dir file.xxx > nul, aún verá la parte del mensaje de error de la salida, así:

File Not Found

Para redirigir (solo) el mensaje de error NUL, use el siguiente comando:

dir file.xxx 2> nul

O bien, puede redirigir la salida a un lugar y los errores a otro.

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

Puede imprimir los errores y la salida estándar en un solo archivo utilizando el comando "& 1" para redirigir la salida de STDERR a STDOUT y luego enviar la salida de STDOUT a un archivo:

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

Para agregar stdout y stderr al archivo de registro general de un script:

dir >> a.txt 2>&1
Henk Wiersema
fuente
99
El se >>agrega al archivo donde se >sobrescribe el archivo.
delliottg
13

Correcto, el identificador de archivo 1 para el proceso es STDOUT, redirigido por 1>o por >(1 puede omitirse, por convención, el intérprete de comandos [cmd.exe] sabe manejar eso). El identificador de archivo 2 es STDERR, redirigido por 2>.

Tenga en cuenta que si los está utilizando para crear archivos de registro, a menos que esté enviando la salida a _uniquely_named_ (por ejemplo, fecha y hora con sello), si ejecuta el mismo proceso dos veces, el redireccionado sobrescribirá ( reemplazar) el archivo de registro anterior.

El >>(para STDOUT o STDERR) APENDERÁ, NO REEMPLAZARÁ el archivo. Entonces obtienes un archivo de registro acumulativo, que muestra los resultados de todas las ejecuciones del proceso, generalmente más útil.

Rastros felices...

Max Vitesse
fuente
2

Sin embargo, no hay garantía de que la salida de SDTOUTy STDERRse entrelacen línea por línea en el orden oportuno, utilizando la POSIXsintaxis de combinación de redireccionamiento.

Si una aplicación usa una salida almacenada en búfer, puede suceder que el texto de una secuencia se inserte en la otra en un límite de búfer, que puede aparecer en el medio de una línea de texto.

Un registrador de salida de consola dedicado (es decir, "StdOut/StdErr Logger"by 'LoRd MuldeR') puede ser más confiable para tal tarea.

Ver: Proyectos de código abierto de MuldeR

LIGH
fuente
0

En un archivo por lotes (Windows 7 y superior) encontré este método más confiable

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

Obviamente, use los comandos que desee y la salida se dirigirá al archivo de texto. El uso de este método es confiable SIN EMBARGO, NO hay salida en la pantalla.

PanamaPHat
fuente
(Básicamente, la misma respuesta que se dio hace unos años). Puede forzar la salida a la pantalla con >con echo This goes to screenTambién es útil para la entrada del usuario >con set /p "var="Input: "Nota: esas líneas solo aparecerán en la pantalla y no se redirigirán al archivo.
Stephan