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?
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.
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
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.
La solution qui a fonctionné pour moi était la suivante: dir> a.txt | type a.txt .
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
command > file >&1
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
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.
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
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.
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.