batch-file - studio - uso del comando ver
Mostrar la salida del sÃmbolo del sistema de Windows y redirigirla a un archivo (27)
¿Cómo puedo ejecutar una aplicación de línea de comandos en el símbolo del sistema de Windows y tener la salida mostrada y redirigida a un archivo al mismo tiempo?
Si, por ejemplo, ejecutara el comando dir > test.txt
, esto redirigiría la salida a un archivo llamado test.txt
sin mostrar los resultados.
¿Cómo podría escribir un comando para mostrar la salida y redirigir la salida a un archivo en el símbolo del sistema de Windows, similar al comando tee
en Unix?
¿Cómo puedo mostrar y redirigir la salida a un archivo. Supongamos que si utilizo el comando dos, dir> test.txt, este comando redireccionará la salida al archivo test.txt sin mostrar los resultados. cómo escribir un comando para mostrar la salida y redirigir la salida a un archivo utilizando DOS, es decir, el símbolo del sistema de Windows, no en UNIX / LINUX.
Puede encontrar estos comandos en biterscripting ( http://www.biterscripting.com ) útiles.
var str output
lf > $output
echo $output # Will show output on screen.
echo $output > "test.txt" # Will write output to file test.txt.
system start "test.txt" # Will open file test.txt for viewing/editing.
¿Algo así debería hacer lo que necesitas?
%DATE%_%TIME% > c:/a.txt & type c:/a.txt
ipconfig >> c:/a.txt & type c:/a.txt
ping localhost >> c:/a.txt & type c:/a.txt
pause
@ tori3852
encontre eso
dir > a.txt | type a.txt
no funcionó (solo las primeras líneas de la lista de dirs. ¿sospecha de algún tipo de proceso de bifurcación y la segunda parte, el comando ''tipo'' finalizó antes de que se completara la lista?), así que en lugar de eso utilicé:
dir > z.txt && type z.txt
que hizo - comandos secuenciales, uno completa antes de que comience el segundo.
Al igual que unix
dir | tee a.txt
funciona en Windows XP, requiere mksnt instalado
Se muestra en el promt, así como en el archivo.
Aquí hay una muestra de lo que he usado basado en una de las otras respuestas.
@echo off
REM SOME CODE
set __ERROR_LOG=c:/errors.txt
REM set __IPADDRESS=x.x.x.x
REM Test a variable
if not defined __IPADDRESS (
REM Call function with some data and terminate
call :TEE %DATE%,%TIME%,IP ADDRESS IS NOT DEFINED
goto :EOF
)
REM If test happens to be successful, TEE out a message and end script.
call :TEE Script Ended Successful
goto :EOF
REM THE TEE FUNCTION
:TEE
for /f "tokens=*" %%Z in ("%*") do (
> CON ECHO.%%Z
>> "%__ERROR_LOG%" ECHO.%%Z
goto :EOF
)
Desafortunadamente no hay tal cosa.
Las aplicaciones de la consola de Windows solo tienen un controlador de salida único. (Bueno, hay dos STDOUT
, STDERR
pero no importa aquí) >
redirige la salida que normalmente se escribe en el identificador de la consola a un identificador de archivo.
Si desea tener algún tipo de multiplexación, tiene que usar una aplicación externa a la que puede desviar la salida. Esta aplicación puede escribir en un archivo y en la consola de nuevo.
Esta es una variación de una answer anterior de MTS, sin embargo, agrega algunas funciones que podrían ser útiles para otros. Aquí está el método que utilicé:
- Un comando se establece como una variable, que se puede usar más adelante en todo el código, para enviar a la ventana de comandos y adjuntarla a un archivo de registro, usando
set _Temp_Msg_Cmd=
- el comando ha escapado a la redirection utilizando el carácter de zanahoria
^
para que los comandos no se evalúen inicialmente
- el comando ha escapado a la redirection utilizando el carácter de zanahoria
- Se crea un archivo temporal con un nombre de archivo similar al archivo por lotes que se ejecuta llamado
%~n0_temp.txt
que usa la sintaxis de la extensión del parámetro de la línea de comandos%~n0
para obtener el nombre del archivo por lotes. - La salida se adjunta a un archivo de registro independiente
%~n0_log.txt
Aquí está la secuencia de comandos:
- Los mensajes de salida y de error se envían al archivo temporal
^> %~n0_temp.txt 2^>^&1
- El contenido del archivo temporal es a la vez:
- adjuntado al archivo de registro
^& type %~n0_temp.txt ^>^> %~n0_log.txt
- salida a la ventana de comandos
^& type %~n0_temp.txt
- adjuntado al archivo de registro
- El archivo temporal con el mensaje se eliminó
^& del /Q /F %~n0_temp.txt
Aquí está el ejemplo:
set _Temp_Msg_Cmd= ^> %~n0_temp.txt 2^>^&1 ^& type %~n0_temp.txt ^>^> %~n0_log.txt ^& type %~n0_temp.txt ^& del /Q /F %~n0_temp.txt
De esta manera, el comando puede simplemente agregarse después de los comandos posteriores en un archivo por lotes que se ve mucho más limpio:
echo test message %_Temp_Msg_Cmd%
Esto también se puede agregar al final de otros comandos. Por lo que sé, funcionará cuando los mensajes tengan varias líneas. Por ejemplo, el siguiente comando genera dos líneas si hay un mensaje de error:
net use M: /D /Y %_Temp_Msg_Cmd%
Esto funciona en tiempo real, pero también es algo feo y el rendimiento es lento. Tampoco está bien probado:
@echo off
cls
SET MYCOMMAND=dir /B
ECHO File called ''test.bat'' > out.txt
for /f "usebackq delims=" %%I in (`%MYCOMMAND%`) do (
ECHO %%I
ECHO %%I >> out.txt
)
pause
Esto funciona, aunque es un poco feo:
dir >_ && type _ && type _ > a.txt
Es un poco más flexible que algunas de las otras soluciones, ya que funciona declaración por declaración, por lo que también puede usarlo para agregar. Lo uso bastante en los archivos por lotes para registrar y mostrar mensajes:
ECHO Print line to screen and log to file. >_ && type _ && type _ >> logfile.txt
Sí, podría repetir la instrucción ECHO (una vez para la pantalla y la segunda para redirigir al archivo de registro), pero se ve tan mal y es un problema de mantenimiento. Al menos de esta manera, no tiene que hacer cambios a los mensajes en dos lugares.
Tenga en cuenta que _ es solo un nombre de archivo corto, por lo que deberá asegurarse de eliminarlo al final de su archivo por lotes (si está utilizando un archivo por lotes).
Estoy de acuerdo con Brian Rasmussen, el puerto unxutils es la forma más fácil de hacer esto. En la sección Archivos por lotes de sus páginas de secuencias de comandos, Rob van der Woude proporciona una gran cantidad de información sobre el uso de los comandos MS-DOS y CMD. Pensé que podría tener una solución nativa para su problema y, después de investigar allí, encontré TEE.BAT , que parece ser solo eso, una implementación de T de MS-DOS en lenguaje por lotes. Es un archivo por lotes de aspecto bastante complejo y mi inclinación aún sería utilizar el puerto unxutils.
Hay un puerto Win32 del comando tee
Unix, que hace exactamente eso. Consulte http://unxutils.sourceforge.net/ o http://getgnuwin32.sourceforge.net/
Instalo perl en la mayoría de mis máquinas, así que respondo usando perl: tee.pl
my $file = shift || "tee.dat";
open $output, ">", $file or die "unable to open $file as output: $!";
while(<STDIN>)
{
print $_;
print $output $_;
}
close $output;
dir | perl tee.pl o dir | perl tee.pl dir.bat
crudo y no probado.
La siguiente información le ayudará si desea ver algo realmente en la pantalla, incluso si el archivo por lotes se redirigió a un archivo. El dispositivo CON puede usarse también si se redirige a un archivo
Ejemplo:
ECHO first line on normal stdout. maybe redirected
ECHO second line on normal stdout again. maybe redirected
ECHO third line is to ask the user. not redirected >CON
ECHO fourth line on normal stdout again. maybe redirected
También vea una buena descripción de redirección: http://www.p-dd.com/chapter7-page14.html
Me gustaría ampliar un poco la excelente respuesta de Saxon Druce.
Como se indicó, puede redirigir la salida de un ejecutable en el directorio actual de la siguiente manera:
powershell "./something.exe | tee test.txt"
Sin embargo, esto solo registra la test.txt
en test.txt
. También no registra stderr
.
La solución obvia sería usar algo como esto:
powershell "./something.exe 2>&1 | tee test.txt"
Sin embargo, esto no funcionará para todos los something.exe
. Algunos something.exe
s interpretarán el 2>&1
como un argumento y fallarán. La solución correcta es, en cambio, tener solo apóstrofes alrededor de something.exe
y sus interruptores y argumentos, como:
powershell "./something.exe --switch1 --switch2 … arg1 arg2 …" 2>&1 | tee test.txt
Mira esto:
No hay necesidad de cygwin.
Sin embargo encontré e informé algunos problemas.
También puede revisar http://unxutils.sourceforge.net/ porque contiene tee (y no es necesario para cygwin), pero tenga en cuenta que los EOL de salida son similares a UNIX aquí.
Por último, pero no menos importante, es que si tienes PowerShell, puedes probar Tee-Object. Escriba get-help tee-object
en la consola de PowerShell para obtener más información.
Para ampliar la respuesta de Davor , puedes usar PowerShell así:
powershell "dir | tee test.txt"
Si está intentando redirigir la salida de un archivo ejecutable en el directorio actual, necesita usar ./
En el nombre de archivo, por ejemplo:
powershell "./something.exe | tee test.txt"
Pude encontrar una solución / solución alternativa para redireccionar la salida a un archivo y luego a la consola:
dir > a.txt | type a.txt
donde dir es el comando que debe redirigirse a la salida , a.txt un archivo donde almacenar la salida.
Sé que este es un tema muy antiguo, pero en las respuestas anteriores no hay una implementación completa de una camiseta en tiempo real escrita en lote. Mi solución a continuación es un script híbrido Batch-JScript que usa la sección JScript solo para obtener el resultado del comando canalizado, pero el procesamiento de los datos se realiza en la sección Batch. Este enfoque tiene la ventaja de que cualquier programador por lotes puede modificar este programa para satisfacer necesidades específicas. Este programa también procesa correctamente la salida del comando CLS producido por otros archivos por lotes, es decir, borra la pantalla cuando se detecta la salida del comando CLS.
@if (@CodeSection == @Batch) @then
@echo off
setlocal EnableDelayedExpansion
rem APATee.bat: Asynchronous (real time) Tee program, Batch-JScript hybrid version
rem Antonio Perez Ayala
rem The advantage of this program is that the data management is written in Batch code,
rem so any Batch programmer may modify it to fit their own needs.
rem As an example of this feature, CLS command is correctly managed
if "%~1" equ "" (
echo Duplicate the Stdout output of a command in the screen and a disk file
echo/
echo anyCommand ^| APATee teeFile.txt [/A]
echo/
echo If /A switch is given, anyCommand output is *appended* to teeFile.txt
goto :EOF
)
if "%2" equ ":TeeProcess" goto TeeProcess
rem Get the output of CLS command
for /F %%a in (''cls'') do set "cls=%%a"
rem If /A switch is not provided, delete the file that receives Tee output
if /I "%~2" neq "/A" if exist %1 del %1
rem Create the semaphore-signal file and start the asynchronous Tee process
echo X > Flag.out
if exist Flag.in del Flag.in
Cscript //nologo //E:JScript "%~F0" | "%~F0" %1 :TeeProcess
del Flag.out
goto :EOF
:TeeProcess
rem Wait for "Data Available" signal
if not exist Flag.in goto TeeProcess
rem Read the line sent by JScript section
set line=
set /P line=
rem Set "Data Read" acknowledgement
ren Flag.in Flag.out
rem Check for the standard "End Of piped File" mark
if "!line!" equ ":_EOF_:" exit /B
rem Correctly manage CLS command
if "!line:~0,1!" equ "!cls!" (
cls
set "line=!line:~1!"
)
rem Duplicate the line in Stdout and the Tee output file
echo(!line!
echo(!line!>> %1
goto TeeProcess
@end
// JScript section
var fso = new ActiveXObject("Scripting.FileSystemObject");
// Process all lines of Stdin
while ( ! WScript.Stdin.AtEndOfStream ) {
// Read the next line from Stdin
var line = WScript.Stdin.ReadLine();
// Wait for "Data Read" acknowledgement
while ( ! fso.FileExists("Flag.out") ) {
WScript.Sleep(10);
}
// Send the line to Batch section
WScript.Stdout.WriteLine(line);
// Set "Data Available" signal
fso.MoveFile("Flag.out", "Flag.in");
}
// Wait for last "Data Read" acknowledgement
while ( ! fso.FileExists("Flag.out") ) {
WScript.Sleep(10);
}
// Send the standard "End Of piped File" mark
WScript.Stdout.WriteLine(":_EOF_:");
fso.MoveFile("Flag.out", "Flag.in");
Si tiene cygwin en la ruta del entorno de Windows, puede usar:
dir > a.txt | tail -f a.txt
También estaba buscando la misma solución; después de un pequeño intento, pude lograrla con éxito en el símbolo del sistema. Aquí está mi solución:
@Echo off
for /f "Delims=" %%a IN (xyz.bat) do (
%%a > _ && type _ && type _ >> log.txt
)
@Echo on
Incluso captura cualquier comando PAUSA también.
Una alternativa es enviar la salida estándar a stderr dentro de su programa:
en java:
System.setOut(new PrintStream(new TeeOutputStream(System.out, System.err)));
Luego, en tu dos batchfile: java program > log.txt
El stdout irá al archivo de registro y el stderr (los mismos datos) se mostrará en la consola.
Una simple aplicación de consola C # haría el truco:
using System;
using System.Collections.Generic;
using System.IO;
namespace CopyToFiles
{
class Program
{
static void Main(string[] args)
{
var buffer = new char[100];
var outputs = new List<TextWriter>();
foreach (var file in args)
outputs.Add(new StreamWriter(file));
outputs.Add(Console.Out);
int bytesRead;
do
{
bytesRead = Console.In.ReadBlock(buffer, 0, buffer.Length);
outputs.ForEach(o => o.Write(buffer, 0, bytesRead));
} while (bytesRead == buffer.Length);
outputs.ForEach(o => o.Close());
}
}
}
Para usar esto, simplemente coloque el comando fuente en el programa y proporcione la ruta de acceso de los archivos a los que desea duplicar la salida. Por ejemplo:
dir | CopyToFiles files1.txt files2.txt
Mostrará los resultados de dir y almacenará los resultados tanto en files1.txt como en files2.txt.
Tenga en cuenta que no hay mucho (¡nada!) En el modo de manejo de errores anterior, y es posible que no sea necesario admitir múltiples archivos.
Utilizo una subrutina por lotes con una declaración "for" para obtener el comando de salida una línea a la vez y ambos escriben esa línea en un archivo y la envían a la consola.
@echo off
set logfile=test.log
call :ExecuteAndTee dir C:/Program Files
Exit /B 0
:ExecuteAndTee
setlocal enabledelayedexpansion
echo Executing ''%*''
for /f "delims=" %%a in (''%* 2^>^&1'') do (echo.%%a & echo.%%a>>%logfile%)
endlocal
Exit /B 0
envíe la salida a la consola, agregue a la consola el registro, elimine la salida del comando actual
dir >> usb-create.1 && type usb-create.1 >> usb-create.log | type usb-create.1 && del usb-create.1
mtee es una pequeña utilidad que funciona muy bien para este propósito. Es gratis, la fuente está abierta, y simplemente funciona.
Lo puedes encontrar en http://www.commandline.co.uk .
Usado en un archivo por lotes para mostrar la salida Y crear un archivo de registro simultáneamente, la sintaxis se ve así:
someprocess | mtee /+ mylogfile.txt
Donde / + significa añadir la salida.
Esto supone que ha copiado mtee en una carpeta que está en la RUTA, por supuesto.
dir 1>a.txt 2>&1 | type a.txt
Esto ayudará a redirigir tanto STDOUT como STDERR.
@echo on
set startDate=%date%
set startTime=%time%
set /a sth=%startTime:~0,2%
set /a stm=1%startTime:~3,2% - 100
set /a sts=1%startTime:~6,2% - 100
fullprocess.bat > C:/LOGS/%startDate%_%sth%.%stm%.%sts%.LOG | fullprocess.bat
Esto creará un archivo de registro con la fecha y hora actual y podrá ver las líneas de la consola durante el proceso.