web-dev-qa-db-fra.com

Comment puis-je faire écho et envoyer la sortie de la console à un fichier dans un script bat?

J'ai un script batch qui exécute une tâche et envoie la sortie dans un fichier texte. Existe-t-il un moyen d’afficher la sortie dans la fenêtre de la console?

Par exemple:

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

Existe-t-il un moyen d’afficher la sortie de dir dans la fenêtre de la console et de la placer dans le fichier texte?

132
JamesEggers

Non, vous ne pouvez pas avec la redirection pure.
Mais avec quelques astuces (comme tee.bat ) vous pouvez.

J'essaie d'expliquer un peu la redirection.

Vous redirigez l'un des dix flux avec > fichier ou <fichier
Peu importe, si la redirection se situe avant ou après la commande, ces deux lignes sont presque identiques.

dir > file.txt
> file.txt dir

La redirection dans cet exemple n'est qu'un raccourci pour 1> , cela signifie que le flux 1 (STDOUT) sera redirigé.
Ainsi, vous pouvez rediriger n'importe quel flux avec le numéro précédant le numéro du type 2> err.txt et il est également permis de rediriger plusieurs flux en un seul. ligne.

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

Dans cet exemple, la "sortie standard" sera insérée dans le fichier files.txt, toutes les erreurs seront dans err.txt et le flux3 n'entrera dans rien.txt (DIR n'utilise pas le flux 3).
Stream0 est STDIN
Stream1 est STDOUT
Stream2 est STDERR
Stream3-9 ne sont pas utilisés

Mais que se passe-t-il si vous essayez de rediriger le même flux plusieurs fois?

dir > files.txt > two.txt

"Il ne peut y avoir qu'un seul", et c'est toujours le dernier!
Donc, il est égal à dir> deux.txt

Ok, il y a une possibilité supplémentaire, rediriger un flux vers un autre flux.

dir 1>files.txt 2>&1 

2> & 1 redirige stream2 vers stream1 et 1> fichiers.txt redirige tout à files.txt .
L'ordre est important ici!

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

sont différents. Le premier redirige tout (STDOUT et STDERR) vers NUL,
mais la deuxième ligne redirige le STDOUT vers NUL et STDERR vers le STDOUT "vide".

En guise de conclusion, il est évident que les exemples d’Otávio Décio et d’andynormancx ne fonctionnent pas.

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

Les deux essaient de rediriger stream1 deux fois, mais "Il ne peut y en avoir qu'un", et c'est toujours le dernier.
Alors vous obtenez

command 1>&1
dir 1>&2

Et dans le premier exemple, la redirection de stream1 vers stream1 n'est pas autorisée (et pas très utile).

J'espère que ça aide.

211
jeb

Utilisez simplement la version Windows de la commande UNIX tee (trouvée à partir de http://unxutils.sourceforge.net ) de cette façon:

mycommand > tee outpu_file.txt

Si vous avez également besoin de la sortie STDERR, utilisez ce qui suit.
Le 2>&1 combine la sortie STDERR dans STDOUT (le flux primaire).

mycommand 2>&1 | tee output_file.txt
32
atn

Si vous n’avez pas besoin de la sortie en temps réel (c’est-à-dire pendant que le programme l’écrit), vous pouvez ajouter

type windows-dir.txt

après cette ligne.

9
Mark Pim

La solution qui a fonctionné pour moi était la suivante: dir> a.txt | type a.txt .

7

Oui, il existe un moyen d'afficher une sortie de commande unique sur la console (écran) et dans un fichier. En utilisant votre exemple, utilisez ...

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

Explication détaillée:

La commande FOR analyse la sortie d'une commande ou du texte dans une variable, qui peut être référencée plusieurs fois.

Pour une commande, telle que DIR /B, mettez les guillemets simples, comme indiqué dans l'exemple ci-dessous. Remplacez le texte DIR /B par la commande souhaitée.

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

Pour afficher du texte, placez-le entre guillemets, comme indiqué dans l'exemple ci-dessous.

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

... Et avec le retour à la ligne ...

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

Si vous souhaitez parfois que la sortie ne soit affichée que sur console (écran) et si elle est envoyée uniquement dans un fichier, envoyez-la à la fois, spécifiez la clause "DO" de la boucle FOR à l'aide d'une variable, comme indiqué ci-dessous avec %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
6
Amazinate
command > file >&1
3
Otávio Décio

Si vous voulez ajouter au lieu de remplacer le fichier de sortie, vous pouvez utiliser

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

ou

dir 1>> files.txt 2>>&1
2
Jochen

J'aime la réponse d'Atn, mais ce n'était pas aussi simple pour moi de télécharger en tant que wintee , qui est également open source et ne donne que la fonctionnalité tee (utile si vous voulez juste un tee et pas un ensemble complet d'unix utilitaires). J'ai appris cela par la réponse de davor à Affichage de la sortie de la commande Windows et redirection vers un fichier , où vous trouverez également une référence aux utilitaires Unix.

1
sage

J'ai créé une simple console C # capable de gérer la sortie en temps réel vers l'écran de contrôle et le journal

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;
    }
}

L'utilisation du fichier de commandes est la même que celle utilisée sous Unix tee

foo | tee xxx.log

Et voici le référentiel qui inclut le fichier Tee.exe au cas où vous ne possédez pas d’outil pour compiler https://github.com/iamshiao/Tee

1
蕭為元

Mon option était la suivante:

Créez un sous-programme qui prend en compte le message et automatise le processus d’envoi à la fois à la console et au fichier journal.

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 vous ajoutez une variable au message, assurez-vous de supprimer les guillemets avant de l'envoyer au sous-programme, sinon cela risque de nuire à votre lot. Bien sûr, cela ne fonctionne que pour faire écho.

1
JPZ

La solution fournie par "Tomas R" fonctionne parfaitement pour la question du PO et est disponible nativement.

Essayez: chkdsk c:> output.txt | tapez output.txt

La sortie de cette commande implique un pourcentage d’achèvement qui est envoyé en série dans le fichier, de sorte que le résultat sera un peu brouillon (c’est-à-dire que le texte sera ajouté au fur et à mesure de son avancement). Cela ne se produit pas avec les bits qui sortent dans STDOUT (l’écran). C'est comme ça si vous faisiez la même commande sans redirection.

0
J0N