web-dev-qa-db-fra.com

Affichage de l’invite de la commande Windows et redirection vers un fichier

Comment puis-je exécuter une application de ligne de commande dans l'invite de commande Windows et afficher le résultat et le rediriger simultanément vers un fichier?

Si, par exemple, je devais exécuter la commande dir > test.txt, la sortie serait redirigée vers un fichier nommé test.txt sans afficher les résultats.

Comment écrire une commande pour afficher la sortie and rediriger la sortie vers un fichier dans l'invite de commande Windows, similaire à la commande tee de Unix?

344
Ammu

Pour développer davor's answer , vous pouvez utiliser PowerShell de la manière suivante:

powershell "dir | tee test.txt"

Si vous essayez de rediriger la sortie d'un fichier exe dans le répertoire en cours, vous devez utiliser .\ sur le nom du fichier, par exemple:

powershell ".\something.exe | tee test.txt"
132
Saxon Druce

J'ai été capable de trouver une solution/solution de contournement de la sortie vers un fichier et ensuite vers la console:

dir > a.txt | type a.txt

dir est la commande dont la sortie doit être redirigée, a.txt un fichier où stocker la sortie.

127

Il existe un port Win32 de la commande Unix tee, qui fait exactement cela. Voir http://unxutils.sourceforge.net/ ou http://getgnuwin32.sourceforge.net/

92
Brian Rasmussen

Vérifiez ceci: wintee

Pas besoin de cygwin.

J'ai rencontré et signalé quelques problèmes cependant.

Vous pouvez aussi vérifier nxutils car il contient un tee (et aucun besoin de cygwin), mais sachez que les fichiers EOL en sortie ressemblent à UNIX, comme ici.

Dernier point, mais non le moindre, si vous avez PowerShell, vous pouvez essayer Tee-Object. Tapez get-help tee-object dans la console PowerShell pour plus d'informations.

48
Davor Josipovic

@ tori3852

Je l'ai trouvé

dir > a.txt | type a.txt

n'a pas fonctionné (les premières lignes de la liste dir seulement - soupçonnent une sorte de processus et la seconde partie, la commande 'type' s'est terminée avant la fin de la liste?), j'ai donc utilisé:

dir > z.txt && type z.txt

qui a fait - des commandes séquentielles, on complète avant le second commence.

43
Andy Welch

Une simple application console C # 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 cela, il vous suffit de canaliser la commande source dans le programme et de fournir le chemin de tous les fichiers pour lesquels vous souhaitez dupliquer la sortie. Par exemple:

dir | CopyToFiles files1.txt files2.txt 

Affiche les résultats de dir et stocke les résultats dans les fichiers files1.txt et files2.txt.

Notez qu'il n'y a pas beaucoup (quoi que ce soit!) De solutions de traitement des erreurs ci-dessus, et la prise en charge de plusieurs fichiers peut ne pas être réellement nécessaire.

22
Richard

Malheureusement, rien de tel.

Les applications de console Windows ne possèdent qu'un seul descripteur de sortie. (Bien, il y a deux STDOUT, STDERR mais cela n'a pas d'importance ici) Le > redirige la sortie normalement écrite dans le descripteur de console vers un descripteur de fichier.

Si vous souhaitez effectuer un multiplexage, vous devez utiliser une application externe vers laquelle vous pouvez renvoyer la sortie. Cette application peut alors écrire dans un fichier et dans la console à nouveau.

21
Daniel Rikowski

Cela fonctionne, même si c'est un peu moche:

dir >_ && type _ && type _ > a.txt

Elle est un peu plus flexible que certaines des autres solutions, en ce sens qu'elle fonctionne instruction par instruction afin que vous puissiez l'utiliser également pour l'ajouter. J'utilise un peu ces fichiers batch pour enregistrer et afficher des messages:

ECHO Print line to screen and log to file.  >_ && type _ && type _ >> logfile.txt

Oui, vous pouvez simplement répéter l’instruction ECHO (une fois pour l’écran et une deuxième fois pour la redirection vers le fichier journal), mais cela semble tout aussi mauvais et représente un problème de maintenance. Au moins, vous ne devrez pas modifier les messages à deux endroits.

Notez que _ n'est qu'un fichier court. Vous devez donc vous assurer de le supprimer à la fin de votre fichier de commandes (si vous utilisez un fichier de commandes).

19
MTS

mété est un petit utilitaire qui fonctionne très bien à cet effet. C'est gratuit, la source est ouverte et ça marche.

Vous pouvez le trouver à http://www.commandline.co.uk .

Utilisée dans un fichier de commandes pour afficher la sortie ET créer un fichier journal simultanément, la syntaxe est la suivante:

    someprocess | mtee /+ mylogfile.txt

Où/+ signifie ajouter la sortie.

Cela suppose que vous avez copié mtee dans un dossier qui se trouve dans le PATH, bien sûr.

16
Mark

Je suis d'accord avec Brian Rasmussen, le port unxutils est le moyen le plus simple de procéder. Dans la section Fichiers batch de ses Pages de script , Rob van der Woude fournit une mine d'informations sur l'utilisation des commandes MS-DOS et CMD. Je pensais qu'il aurait peut-être une solution native à votre problème et, après avoir fouillé dans tout cela, j'ai trouvé TEE.BAT , qui semble n'être que cela, une implémentation en langage de traitement par lots de MS-DOS. C'est un fichier batch d'aspect assez complexe et mon penchant serait toujours d'utiliser le portage unxutils.

9
Steve Crane

Si vous avez cygwin dans votre chemin d’environnement Windows, vous pouvez utiliser:

 dir > a.txt | tail -f a.txt
8
jkdba

Je voudrais développer un peu les propos de Saxon Druce’s excellente réponse .

Comme indiqué, vous pouvez rediriger la sortie d'un exécutable dans le répertoire en cours de la manière suivante:

powershell ".\something.exe | tee test.txt"

Cependant, cela enregistre uniquement stdout dans test.txt. Il n’enregistre pas non plus stderr.

La solution évidente serait d'utiliser quelque chose comme ceci:

powershell ".\something.exe 2>&1 | tee test.txt"

Cependant, cela ne fonctionnera pas pour tous les something.exes. Certains something.exes interpréteront le 2>&1 comme un argument et échoueront. La bonne solution est d’avoir seulement des apostrophes autour du something.exe et ses commutateurs et arguments, comme ceci:

powershell ".\something.exe --switch1 --switch2 … arg1 arg2 …" 2>&1 | tee test.txt
8
アリスター

dir 1>a.txt 2>&1 | type a.txt

Cela aidera à rediriger STDOUT et STDERR.

6
rashok

Je recherchais également la même solution. Après un peu d’essais, j’ai réussi à atteindre cet objectif dans Invite de commandes. Voici ma solution:

@Echo off
for /f "Delims=" %%a IN (xyz.bat) do (
%%a > _ && type _ && type _ >> log.txt
)
@Echo on

Il capture même toute commande PAUSE.

4
Koder101

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
3
Richard K

Voici un exemple de ce que j'ai utilisé à partir d'une autre réponse

@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
)
3
Ed Radke

Je sais que c'est un sujet très ancien, mais dans les réponses précédentes, l'implémentation d'un té en temps réel écrit en batch n'est pas complète. Ma solution ci-dessous est un script hybride Batch-JScript qui utilise la section JScript uniquement pour obtenir le résultat de la commande piped, mais le traitement des données est effectué dans la section Batch. Cette approche présente l’avantage que tout programmeur Batch peut modifier ce programme pour répondre à des besoins spécifiques. Ce programme traite également correctement la sortie de la commande CLS produite par d’autres fichiers Batch, c’est-à-dire qu’il efface l’écran lorsque la sortie de la commande CLS est détectée.

@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");
3
Aacini

envoyer la sortie à la console, ajouter au journal de la console, supprimer la sortie de la commande en cours

dir  >> usb-create.1 && type usb-create.1 >> usb-create.log | type usb-create.1 && del usb-create.1
3
Dennis
@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 l’heure actuelle et vous pourrez utiliser les lignes de la console pendant le processus.

2
7thSphere

Il s’agit d’une variante du précédent answer de MTS, qui ajoute toutefois certaines fonctionnalités pouvant être utiles à d’autres. Voici la méthode que j'ai utilisée:

  • Une commande est définie en tant que variable, qui peut être utilisée ultérieurement dans tout le code, pour être affichée dans la fenêtre de commande et ajoutée à un fichier journal à l'aide de set _Temp_Msg_Cmd= .
    • la commande s'est échappée redirection en utilisant le caractère carot ^ afin que les commandes ne soient pas évaluées initialement
  • Un fichier temporaire est créé avec un nom de fichier similaire au fichier de commandes en cours d'exécution appelé %~n0_temp.txt qui utilise syntaxe d'extension de paramètre de ligne de commande%~n0 pour obtenir le nom du fichier de commandes.
  • La sortie est ajoutée à un fichier journal séparé %~n0_log.txt

Voici la séquence de commandes:

  1. Les messages de sortie et d’erreur sont envoyés au fichier temporaire ^> %~n0_temp.txt 2^>^&1
  2. Le contenu du fichier temporaire est alors à la fois:
    • ajouté au fichier journal ^& type %~n0_temp.txt ^>^> %~n0_log.txt
    • sortie dans la fenêtre de commande ^& type %~n0_temp.txt
  3. Le fichier temporaire contenant 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 simplement être ajoutée après les commandes ultérieures dans un fichier de commandes qui semble beaucoup plus propre:

echo test message %_Temp_Msg_Cmd%

Cela peut également être ajouté à la fin des autres commandes. Autant que je sache, cela fonctionnera lorsque les messages ont plusieurs lignes. Par exemple, la commande suivante génère deux lignes en cas de message d'erreur:

Net Use M: /D /Y %_Temp_Msg_Cmd%

2
ClearBlueSky85

Juste comme Unix.

dir | tee a.txt

Cela fonctionne-t-il sur Windows XP, il faut que mksnt soit installé.

Il s’affiche sur l’invite et s’ajoute au fichier.

1
user2346926

Si vous êtes sur la CLI, pourquoi ne pas utiliser une boucle FOR pour "FAIRE" ce que vous voulez:

for /F "delims=" %a in ('dir') do @echo %a && echo %a >> output.txt

Excellente ressource sur Windows CMD pour les boucles: https://ss64.com/nt/for_cmd.html La clé ici consiste à définir les délimètres (delims), qui rompraient chaque ligne de sortie, en rien . De cette façon, il ne sera pas cassé sur le défaut d'espace blanc. Le% a est une lettre arbitraire, mais il est utilisé dans la section "faire" pour, eh bien ... faire quelque chose avec les caractères qui ont été analysés à chaque ligne. Dans ce cas, vous pouvez utiliser les esperluettes (&&) pour exécuter la commande 2nd echo afin de créer ou d'ajouter (>>) à un fichier de votre choix. Il est plus sûr de conserver cet ordre de commandes DO au cas où il y aurait un problème lors de l'écriture du fichier. Au moins, nous enverrons d'abord l'écho à la console. Le signe at (@) en face du premier écho empêche la console d'afficher la commande echo elle-même et affiche simplement le résultat de la commande qui consiste à afficher les caractères dans% a. Sinon, vous verriez:

echo Volume dans le lecteur [x] est Windows
Le volume dans le lecteur [x] correspond à Windows.

UPDATE:/F ignore les lignes vierges et seul correctif consiste à pré-filtrer la sortie en ajoutant un caractère à chaque ligne (éventuellement avec des numéros de ligne via la commande find). La résolution de ce problème dans l'interface de ligne de commande n'est ni rapide ni jolie. De plus, je n’ai pas inclus STDERR, alors voici des erreurs de capture:

for /F "delims=" %a in ('dir 2^>^&1') do @echo %a & echo %a >> output.txt

redirection des messages d'erreur

Les carets (^) sont là pour échapper aux symboles qui les suivent, car la commande est une chaîne interprétée, par opposition à une saisie directe sur la ligne de commande.

1
Had To Ask

J'utilise un sous-programme batch avec une instruction "for" pour obtenir la sortie de la commande ligne par ligne et les deux écrivent cette ligne dans un fichier et la renvoient sur 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
1
Cody Barnes

Une alternative consiste à choisir stdout to stderr dans votre programme:

en Java:

System.setOut(new PrintStream(new TeeOutputStream(System.out, System.err)));

Ensuite, dans votre fichier batch DOS: Java program > log.txt

La stdout ira au fichier journal et la stderr (mêmes données) s'affichera sur la console.

0
The Coordinator

Une autre variante consiste à scinder le tuyau, puis à rediriger la sortie comme vous le souhaitez.

    @echo off
    for /f "tokens=1,* delims=:" %%P in ('findstr /n "^"') do (
      echo.%%Q
      echo.%%Q>&3
    )
    @exit/b %errorlevel%

Enregistrez ce qui précède dans un fichier .bat. Il divise également la sortie texte de filestream 1 en filestream 3, que vous pouvez rediriger au besoin. Dans mes exemples ci-dessous, j'ai appelé le script ci-dessus splitPipe.bat ...

    dir | splitPipe.bat  1>con  2>&1  3>my_stdout.log

    splitPipe.bat 2>nul < somefile.txt
0
user3726414

J'installe Perl sur la plupart de mes machines, donc une réponse à l'aide de 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.bat

brut et non testé.

0
DannyK

Cela fonctionne en temps réel mais est aussi un peu moche 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
0
djangofan

Comment puis-je afficher et rediriger la sortie vers un fichier. Supposons que si j'utilise la commande dos, dir> test.txt, cette commande redirige la sortie vers le fichier test.txt sans afficher les résultats. comment écrire une commande pour afficher la sortie et rediriger la sortie vers un fichier à l'aide de DOS, c'est-à-dire l'invite de commande Windows, pas sous UNIX/LINUX.

Vous pouvez trouver ces commandes en biterscripting ( http://www.biterscripting.com ) utiles.

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.
0
P M

Suivre aide si vous voulez quelque chose de vraiment vu à l’écran - même si le fichier de commandes a été redirigé vers un fichier. Le périphérique CON peut également ê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 la bonne description de la redirection: http://www.p-dd.com/chapter7-page14.html

0
Baresi der Libero