Affichage de la sortie rapide de la commande Windows et redirection vers un fichier
Comment puis-je exécuter une application en ligne de commande dans L'invite de commande Windows et avoir la sortie affichée et redirigée vers un fichier en même temps?
si, par exemple, je devais exécuter la commande dir > test.txt
, cela redirigerait la sortie vers un fichier appelé test.txt
sans afficher les résultats.
Comment écrire une commande pour afficher la sortie et rediriger la sortie vers un fichier dans la commande Windows prompt, similaire à la commande tee
sur Unix?
27 réponses
j'ai pu trouver une solution / solution de contournement pour rediriger la sortie vers un fichier puis vers la console:
dir > a.txt | type a.txt
où dir est la commande dont la sortie doit être redirigée, a.txt un fichier où stocker la sortie.
pour développer sur réponse de davor , vous pouvez utiliser PowerShell comme ceci:
powershell "dir | tee test.txt"
si vous essayez de rediriger la sortie d'un exe dans le répertoire courant, vous devez utiliser .\
sur le nom du fichier, par exemple:
powershell ".\something.exe | tee test.txt"
il y a un port Win32 de la commande Unix tee
, qui fait exactement cela. Voir http://unxutils.sourceforge.net / ou http://getgnuwin32.sourceforge.net /
Check this out: wintee
pas besoin de cygwin.
j'ai rencontré et rapporté quelques problèmes cependant.
vous pouvez aussi vérifier unxutils parce qu'il contient tee (et pas besoin de cygwin), mais attention que les EOL de sortie sont UNIX-comme ici.
Le Dernier, mais non le moindre, est que si vous avez PowerShell, vous pouvez essayer Tee-Object. Type get-help tee-object
dans Console PowerShell pour plus d'informations.
@tori3852
j'ai trouvé que
dir > a.txt | type a.txt
n'a pas fonctionné (les premières lignes de la liste dir seulement - soupçonner une sorte de bifurcation de processus et la seconde partie, la commande "type" terminé avant la liste dire avait terminé? ), j'ai donc utilisé:
dir > z.txt && type z.txt
qui a fait - commandes séquentielles, une complète avant le deuxième commence.
Malheureusement, il n'y a pas une telle chose.
Windows console applications n'ont qu'une seule poignée de sortie. (Bien, il y a deux STDOUT
, STDERR
mais cela n'a pas d'importance ici) le >
redirige la sortie normalement écrite à la poignée de la console vers une poignée de fichier.
Si vous voulez avoir une sorte de multiplexage vous devez utiliser une application externe qui vous permet de rediriger la sortie. Cette application peut alors écrire dans un fichier et à la console de nouveau.
une simple application c # console ferait l'affaire:
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());
}
}
}
pour utiliser ceci, vous n'avez qu'à insérer la commande source dans le programme et fournir le chemin d'accès de tous les fichiers vers lesquels vous voulez dupliquer la sortie. Par exemple:
dir | CopyToFiles files1.txt files2.txt
affichera les résultats de dir ainsi que stocker les résultats dans les deux files1.txt et files2.txt.
notez qu'il n'y a pas beaucoup (rien!) dans la manière de traiter les erreurs ci-dessus, et prise en charge de plusieurs fichiers peuvent ne pas être nécessaires.
ça marche, même si c'est un peu moche:
dir >_ && type _ && type _ > a.txt
C'est un peu plus souple que celle de certains autres solutions, en ce qu'elle fonctionne instruction par instruction de sorte que vous pouvez l'utiliser pour ajouter. Je l'utilise assez souvent dans les fichiers par lots pour enregistrer et afficher les messages:
ECHO Print line to screen and log to file. >_ && type _ && type _ >> logfile.txt
Oui, vous pouvez simplement répéter la déclaration ECHO (une fois pour l'écran et la deuxième redirection vers le fichier journal), mais cela semble tout aussi mauvais et est un peu d'un problème d'entretien. Au moins de cette façon, vous n'avez pas à faire des changements aux messages à deux endroits.
notez que _ n'est qu'un court nom de fichier, vous devez donc vous assurer de le supprimer à la fin de votre fichier batch (si vous utilisez un fichier batch).
mtee est un petit utilitaire qui fonctionne très bien pour ce but. C'est gratuit, la source est ouverte, et ça fonctionne.
vous pouvez le trouver à http://www.commandline.co.uk .
utilisé dans un fichier batch pour afficher la sortie et créer un fichier log simultanément, la syntaxe ressemble à ceci:
someprocess | mtee /+ mylogfile.txt
Où /+ signifie ajouter la sortie.
Cela suppose que vous avez copié mtee dans un dossier qui est dans le CHEMIN, bien sûr.
Je suis D'accord avec Brian Rasmussen, le port unxutils est la façon la plus facile de le faire. Dans la section fichiers par lots de sa section pages de scripts Rob van der Woude fournit une mine d'informations sur l'utilisation des commandes MS-DOS et CMD. J'ai pensé qu'il pourrait avoir une solution indigène à votre problème et après avoir creusé autour de là j'ai trouvé TEE.BAT , ce qui semble être juste cela, une implémentation MS-DOS du langage de lot de tee. Il est un fichier batch d'apparence assez complexe et mon penchant serait toujours d'utiliser le port unxutils.
je voudrais développer un peu sur Saxon Druce excellente réponse .
Comme indiqué, vous pouvez rediriger la sortie d'un exécutable dans le répertoire courant comme suit:
powershell ".\something.exe | tee test.txt"
Cependant, ce que les logs stdout
à test.txt
. Il n'y a pas non plus de log stderr
.
la solution évidente serait d'utiliser quelque chose comme ceci:
powershell ".\something.exe 2>&1 | tee test.txt"
cependant, ça ne marchera pas pour tous les something.exe
. Certains something.exe
interpréteront le 2>&1
comme un argument et échoueront. La bonne solution est de n'avoir que des apostrophes autour du something.exe
et ce sont des commutateurs et des arguments, comme cela:
powershell ".\something.exe --switch1 --switch2 … arg1 arg2 …" 2>&1 | tee test.txt
si vous avez cygwin dans votre chemin d'environnement windows, vous pouvez utiliser:
dir > a.txt | tail -f a.txt
dir 1>a.txt 2>&1 | type a.txt
Cela va aider à rediriger les deux STDOUT et STDERR
j'étais également à la recherche de la même solution, après un petit essai, j'ai réussi à atteindre ce Prompt de commande. Voici ma solution:
@Echo off
for /f "Delims=" %%a IN (xyz.bat) do (
%%a > _ && type _ && type _ >> log.txt
)
@Echo on
il capture même N'importe quelle commande de PAUSE aussi bien.
envoyer la sortie à la console, ajouter au Journal de la console, supprimer la sortie de la commande courante
dir >> usb-create.1 && type usb-create.1 >> usb-create.log | type usb-create.1 && del usb-create.1
voici un échantillon de ce que j'ai utilisé basé sur l'une des autres réponses
@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
)
@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
cela créera un fichier journal avec le datetime actuel et vous pouvez les lignes de la console pendant le processus
je sais que c'est un sujet très ancien, mais dans les réponses précédentes il n'y a pas une implémentation complète d'un Tee en temps réel écrit en lot. Ma solution ci-dessous est un script Hybride Batch-JScript qui utilise la section JScript juste pour obtenir la sortie de la commande pipée, mais le traitement des données est fait dans la section Batch. Cette approche a l'avantage que n'importe quel programmeur de lot peut modifier ce programme pour s'adapter aux besoins spécifiques. Ce programme traite également correctement la sortie de la commande CLS produit par d'autres fichiers Batch, c'est effacer l'écran lorsque CLS sortie de la commande est détecté.
@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");
quelque chose comme ça devrait faire ce dont vous avez besoin?
%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
C'est une variation sur un précédent réponse par MTS, toutefois, il ajoute quelques fonctionnalités qui pourraient être utiles à d'autres. Voici la méthode que j'ai utilisée:
- une commande est définie comme une variable, qui peut être utilisée plus tard tout au long du code, pour sortir vers la fenêtre de commande et ajouter à un fichier log, en utilisant
set _Temp_Msg_Cmd=
- la commande a échappé redirection en utilisant la carotte
^
caractère de sorte que les commandes ne sont pas évaluées initialement
- la commande a échappé redirection en utilisant la carotte
- un fichier temporaire est créé avec un nom de fichier similaire à celui du fichier par lots appelé
%~n0_temp.txt
qui utilise la syntaxe d'extension de paramètre de ligne de commande%~n0
pour obtenir le nom du fichier par lots. - la sortie est annexée à un fichier journal séparé
%~n0_log.txt
Voici la séquence des commandes:
- les messages de sortie et d'erreur sont envoyés au fichier temporaire
^> %~n0_temp.txt 2^>^&1
- Le contenu du fichier temporaire est alors à la fois:
- annexé au journal
^& type %~n0_temp.txt ^>^> %~n0_log.txt
- sortie vers la fenêtre de commande
^& type %~n0_temp.txt
- annexé au journal
- Le fichier temporaire avec le message est supprimé
^& del /Q /F %~n0_temp.txt
Voici l'exemple:
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 cette façon, la commande peut tout simplement être ajoutée après des commandes ultérieures dans un fichier batch qui semble beaucoup plus propre:
echo test message %_Temp_Msg_Cmd%
Cela peut être ajouté à la fin d'autres commandes. D'après ce que je peux dire, ça marchera quand les messages ont plusieurs lignes. Par exemple, la commande suivante produit deux lignes s'il y a un message d'erreur:
net use M: /D /Y %_Temp_Msg_Cmd%
j'utilise une sous-routine de traitement par lots avec une instruction" for " pour obtenir la sortie de commande une ligne à la fois et à la fois écrire cette ligne dans un fichier et la sortie elle à la console.
@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
ci - dessous aide si vous voulez quelque chose vraiment vu sur l'écran-même si le fichier batch a été redirigé vers un fichier. Le périphérique CON peut aussi être utilisé s'il est redirigé vers un fichier
exemple:
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
Voir aussi bonne redirection description: http://www.p-dd.com/chapter7-page14.html
Comment afficher et rediriger la sortie pour un fichier. Supposons que j'utilise dos commande dir > de test.txt ,cette commande redirigera la sortie vers le test de fichier.txt sans afficher les résultats. comment écrire une commande pour afficher le résultat et rediriger la sortie vers un fichier en utilisant DOS, c'est-à-dire windows command prompt, not sous UNIX/LINUX.
vous pouvez trouver ces commandes dans biterscripting ( http://www.biterscripting.com ) utile.
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.
cela fonctionne en temps réel, mais est aussi gentil un laid et la performance est lente. Pas bien testé non plus:
@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
une alternative est de tee stdout à stderr dans votre programme:
en java:
System.setOut(new PrintStream(new TeeOutputStream(System.out, System.err)));
puis, dans votre dos batchfile: java program > log.txt
le stdout ira dans le fichier log et le stderr (mêmes données) apparaîtra sur la console.
comme unix
dir / tee a.txt
fonctionne sur windows XP, il nécessite mksnt installé
Il les affiche sur le promt ainsi que l'ajoute au fichier
j'installe perl sur la plupart de mes machines donc une réponse en utilisant 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 ou dir / perl tee.pl dir.chauve-souris
brut et non testé.