¿Cómo echo y envío la salida de la consola a un archivo en un script bat?


Tengo un script por lotes que ejecuta una tarea y envía la salida a un archivo de texto. ¿Hay alguna manera de que la salida se muestre también en la ventana de la consola?

Por Ejemplo:

c:\Windows>dir > windows-dir.txt

¿Hay alguna manera de mostrar la salida de dir en la ventana de la consola, así como ponerlo en el archivo de texto?

Author: Ross Ridge, 2009-02-02

11 answers

Bit editado > > tldr; No, no se puede.

Trato de explicar un poco la redirección.

Redirige uno de los diez flujos con > file o
No es importante, si la redirección es antes o después del comando, así que estas dos líneas son casi lo mismo.

dir > file.txt
> file.txt dir

La redirección en este ejemplo es solo un atajo para 1>, esto significa que la secuencia 1 (STDOUT) será redirigida.
Para que pueda redirigir cualquier transmisión con anteponer el número como 2> err.txt y también se permite redirigir múltiples flujos en una línea.

dir 1> files.txt 2> err.txt 3> nothing.txt

En este ejemplo, la "salida estándar" irá a archivos.txt, todos los errores estarán en err.txt y stream3 no entrarán en nada.txt (DIR no usa la secuencia 3).
Stream0 es STDIN
Stream1 es STDOUT
Stream2 is STDERR
Stream3-9 no se utilizan

Pero qué sucede si intenta redirigir el mismo flujo múltiple ¿times?

dir > files.txt > two.txt

"Solo puede haber uno", ¡y siempre es el último!
Así que es igual a dir > dos.txt

Ok, hay una posibilidad adicional, redirigir una secuencia a otra secuencia.

dir 1>files.txt 2>&1 

2>&1 redirige stream2 a stream1 y 1>archivos.txt redirige todos los archivos a .txt.
El orden es importante aquí!

dir ... 1>nul 2>&1
dir ... 2>&1 1>nul

Son diferentes. El primero redirige all (STDOUT y STDERR) a NUL,
pero el segundo line redirige la salida estándar a NUL y STDERR a la salida estándar" vacía".

Como conclusión, es obvio por qué los ejemplos de Otávio Décio y andynormancx no pueden funcionar.

command > file >&1
dir > file.txt >&2

Ambos intentan redirigir stream1 dos veces, pero "solo puede haber uno", y siempre es el último.
Así que obtienes

command 1>&1
dir 1>&2

Y en el primer ejemplo la redirección de stream1 a stream1 no está permitida (y no es muy útil).

Espero que ayude.

 202
Author: jeb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-13 16:35:36

Simplemente use la versión de Windows del comando UNIX tee (encontrado desde http://unxutils.sourceforge.net ) de esta manera:

mycommand > tee outpu_file.txt

Si también necesita la salida STDERR, use lo siguiente.
El 2>&1 combina la salida STDERR en STDOUT (el flujo primario).

mycommand 2>&1 | tee output_file.txt
 29
Author: atn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-12 12:24:59

Si no necesita la salida en tiempo real (es decir, mientras el programa la está escribiendo) puede agregar

type windows-dir.txt

Después de esa línea.

 8
Author: Mark Pim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-02 16:42:41

La solución que funcionó para mí fue: dir > a.txt / tipo a.txt .

 7
Author: NSPKUWCExi2pr8wVoGNk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:50

Sí, hay una manera de mostrar una salida de un solo comando en la consola (pantalla) y en un archivo. Usando su ejemplo, use...

@ECHO OFF
FOR /F "tokens=*" %%I IN ('DIR') DO ECHO %%I & ECHO %%I>>windows-dir.txt

Explicación detallada:

El comando FOR analiza la salida de un comando o texto en una variable, a la que se puede hacer referencia varias veces.

Para un comando, como DIR /B, encierre entre comillas simples como se muestra en el ejemplo a continuación. Reemplace el texto DIR /B con el comando deseado.

FOR /F "tokens=*" %%I IN ('DIR /B') DO ECHO %%I & ECHO %%I>>FILE.TXT

Para mostrar texto, encierre texto en comillas dobles como se muestra en el ejemplo a continuación.

FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO ECHO %%I & ECHO %%I>>FILE.TXT

... Y con envoltura de línea...

FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO (
  ECHO %%I & ECHO %%I>>FILE.TXT
)

Si tiene momentos en los que desea la salida solo en la consola (pantalla), y otras veces enviadas solo al archivo, y otras veces enviadas a ambos, especifique la cláusula "DO" del bucle FOR usando una variable, como se muestra a continuación con %TOECHOWHERE%.

@ECHO OFF
FOR %%I IN (TRUE FALSE) DO (
  FOR %%J IN (TRUE FALSE) DO (
    SET TOSCREEN=%%I & SET TOFILE=%%J & CALL :Runit)
)
GOTO :Finish

:Runit
  REM Both TOSCREEN and TOFILE get assigned a trailing space in the FOR loops
  REM above when the FOR loops are evaluating the first item in the list,
  REM "TRUE".  So, the first value of TOSCREEN is "TRUE " (with a trailing
  REM space), the second value is "FALSE" (no trailing or leading space).
  REM Adding the ": =" text after "TOSCREEN" tells the command processor to
  REM remove all spaces from the value in the "TOSCREEN" variable.
  IF "%TOSCREEN: =%"=="TRUE" (
      IF "%TOFILE: =%"=="TRUE" (
          SET TEXT=On screen, and in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I & ECHO %%I>>FILE.TXT"
        ) ELSE (
          SET TEXT=On screen, not in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I"
      )
    ) ELSE (
      IF "%TOFILE: =%"=="TRUE" (
          SET TEXT=Not on screen, but in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I>>FILE.txt"
        ) ELSE (
          SET TEXT=Not on screen, nor in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I>NUL"
      )
  )
  FOR /F "tokens=*" %%I IN ("%TEXT%") DO %TOECHOWHERE:~1,-1%
GOTO :eof

:Finish
  ECHO Finished [this text to console (screen) only].
  PAUSE
 5
Author: Amazinate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-14 06:28:33
command > file >&1
 3
Author: Otávio Décio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-02 16:41:38

Si desea agregar en lugar de reemplazar el archivo de salida, es posible que desee usar

dir 1>> files.txt 2>> err.txt

O

dir 1>> files.txt 2>>&1
 2
Author: Jochen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-15 12:33:05

Me gusta la respuesta de atn, pero no fue tan trivial para mí descargar como wintee, que también es de código abierto y solo da la funcionalidad tee (útil si solo quieres tee y no todo el conjunto de utilidades unix). Me enteré de esto por la respuesta de davor a Que muestra la salida del símbolo del sistema de Windows y la redirige a un archivo, donde también se encuentra la referencia a las utilidades unix.

 1
Author: sage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:39

Mi opción era esta:

Cree una subrutina que tome el mensaje y automatice el proceso de enviarlo tanto a la consola como al archivo de registro.

setlocal
set logfile=logfile.log

call :screenandlog "%DATE% %TIME% This message goes to the screen and to the log"    

goto :eof

:screenandlog
set message=%~1
echo %message% & echo %message% >> %logfile%
exit /b

Si agrega una variable al mensaje, asegúrese de eliminar las comillas antes de enviarla a la subrutina o puede atornillar su lote. Por supuesto, esto solo funciona para hacer eco.

 1
Author: JPZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-26 11:21:35

Hice una consola simple de C# que puede manejar la salida en tiempo real tanto a la pantalla cmd como al registro

class Tee
{
    static int Main(string[] args)
    {
        try
        {
            string logFilePath = Path.GetFullPath(args[0]);

            using (StreamWriter writer = new StreamWriter(logFilePath, true))
            {
                for (int value; (value = Console.In.Read()) != -1;)
                {
                    var word = Char.ConvertFromUtf32(value);
                    Console.Write(word);
                    writer.Write(word);
                }
            }
        }
        catch (Exception)
        {
            return 1;
        }
        return 0;
    }
}

El uso del archivo por lotes es el mismo que el uso de Unix tee

foo | tee xxx.log

Y aquí está el repositorio que incluye el Tee.exe en caso de que no tengas herramienta para compilar https://github.com/iamshiao/Tee

 1
Author: 蕭為元,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-28 02:31:44

La solución proporcionada por "Tomas R" funciona perfectamente para la pregunta del OP y está disponible de forma nativa.

Pruebe: chkdsk c: > salida.salida txt / type.txt

La salida es de este comando implica un porcentaje de finalización que obtiene una salida en serie al archivo, por lo que se verá un poco desordenado (es decir, el texto se agregará a medida que progrese). Esto no sucede con los bits que obtienen la salida a STDOUT (la pantalla). Es como sería si simplemente hicieras el mismo comando sin redirección.

 0
Author: J0N,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-06 00:32:37