Redirection de la sortie à partir d'un fichier batch

110

Je crée un fichier batch avec quelques commandes simples pour collecter des informations à partir d'un système. Le fichier de commandes contient des commandes pour obtenir l'heure, les informations IP, les utilisateurs, etc.

J'ai assemblé toutes les commandes dans un fichier de commandes, et il s'exécute, mais je voudrais que le fichier de commandes, lorsqu'il est exécuté, affiche les résultats dans un fichier texte (journal). Y a-t-il une commande que je peux ajouter au lot qui le ferait?

Gardez à l'esprit que je ne veux pas exécuter le lot à partir de cmd, puis rediriger la sortie; Je souhaite rediriger la sortie depuis l'intérieur du lot, si cela est possible.

utilisateur3085030
la source

Réponses:

161

La manière naïve simple qui est lente car elle ouvre et positionne le pointeur de fichier plusieurs fois vers la fin du fichier.

@echo off
command1 >output.txt
command2 >>output.txt
...
commandN >>output.txt

Un meilleur moyen - plus facile à écrire et plus rapide car le fichier n'est ouvert et positionné qu'une seule fois.

@echo off
>output.txt (
  command1
  command2
  ...
  commandN
)

Un autre moyen efficace et rapide qui n'ouvre et ne positionne le fichier qu'une seule fois

@echo off
call :sub >output.txt
exit /b

:sub
command1
command2
...
commandN

Modifier 17/04/2020

De temps en temps, vous souhaiterez peut-être écrire à plusieurs reprises dans deux fichiers ou plus. Vous pouvez également souhaiter différents messages à l'écran. Il est toujours possible de le faire efficacement en redirigeant vers des poignées non définies en dehors d'un bloc ou d'un sous-programme entre parenthèses, puis en utilisant la &notation pour référencer les fichiers déjà ouverts.

call :sub 9>File1.txt 8>File2.txt
exit /b

:sub
echo Screen message 1
>&9 File 1 message 1
>&8 File 2 message 1
echo Screen message 2
>&9 File 1 message 2
>&8 File 2 message 2
exit /b

J'ai choisi d'utiliser les poignées 9 et 8 dans l'ordre inverse, car cette méthode est plus susceptible d'éviter une redirection permanente potentielle en raison d'un défaut de conception de l'implémentation de la redirection Microsoft lors de l'exécution de plusieurs redirections sur la même commande. C'est très peu probable, mais même cette approche pourrait exposer le bogue si vous essayez assez fort. Si vous organisez la redirection, vous êtes assuré d'éviter le problème.

3>File1.txt ( 4>File2.txt call :sub)
exit /b

:sub
etc.
Dbenham
la source
2
J'adore les solutions où je peux le définir pour le reste du fichier
Sam
3
Notez que la solution d' appel change votre % 0 (en sous dans ce cas) qui peut ou non être ce que vous voulez.
Jannes
2
@Jannes - True, mais vous pouvez toujours obtenir des informations sur le script batch en cours d'exécution si vous ajoutez un modificateur. Par exemple, %~f0donne toujours le chemin complet du script batch, même à l'intérieur d'un sous-programme CALLed :.
dbenham
3
@ThariqNugrohotomo ->output.txt 2>&1
dbenham
2
@Moondra - c'est la syntaxe de lot standard pour appeler un sous-programme étiqueté dans le même script. Exécutez cmd /?ou à help cmdpartir de la ligne de commande de la console pour la documentation. L'astuce de la troisième méthode est que la redirection sur le CALL s'applique à toutes les commandes dans le sous-programme CALLed.
dbenham le
66

si vous voulez rediriger les flux out et err

dir >> a.txt 2>&1
Kalpesh Soni
la source
27
+1. Il convient également de souligner que l'utilisation >>s'ajoutera à a.txt. Pour remplacer à la a.txtplace, utilisez >. stackoverflow.com/q/4458231/1098302
Aaron
Salut, existe-t-il également un moyen de rediriger la sortie sur la console?
Sandeep Singh le
thats what it
do
16

Je sais que c'est un article plus ancien, mais quelqu'un tombera dessus dans une recherche Google et il semble également que certaines questions posées par le PO dans les commentaires n'aient pas été spécifiquement traitées. Aussi, allez-y doucement car c'est ma première réponse publiée sur SO. :)

Pour rediriger la sortie vers un fichier en utilisant un nom de fichier généré dynamiquement, mon approche go-to (read: quick & dirty) est la deuxième solution proposée par @dbenham. Par exemple, ceci:

@echo off
> filename_prefix-%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log (
echo Your Name Here
echo Beginning Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
REM do some stuff here
echo Your Name Here
echo Ending Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
)

Créera un fichier comme ce que vous voyez dans cette capture d'écran du fichier dans le répertoire cible

Cela contiendra cette sortie:

Your Name Here
Beginning Date/Time: 2016-09-16_141048.log
Your Name Here
Ending Date/Time: 2016-09-16_141048.log

Gardez également à l'esprit que cette solution dépend des paramètres régionaux, alors faites attention à la manière et au moment de l'utiliser.

Anthony
la source
Merci, cela a été utile. Question rapide: y a-t-il une raison pour laquelle vous utilisez .log vs .txt? Cela fait-il une différence?
Moondra
1
@Moondra non, non. C'est juste de la sémantique dans ce cas. Cela ne veut pas dire qu'il n'y a pas d'applications qui nécessitent / grep en fonction du type de fichier, alors soyez juste conscient de si / comment vos fichiers sont utilisés.
Anthony
9
echo some output >"your logfile"

ou

(
 echo some output
 echo more output
)>"Your logfile"

devrait remplir la facture.

Si vous voulez APPENDla sortie, utilisez à la >>place de >. >va démarrer un nouveau fichier journal.

Magoo
la source
9
@echo off
>output.txt (
echo Checking your system infor, Please wating...

systeminfo | findstr /c:"Host Name" 
systeminfo | findstr /c:"Domain"

ipconfig /all | find "Physical Address" 

ipconfig | find "IPv4" 
ipconfig | find "Default Gateway"

)

@pause
saif
la source
Je pense que c'est la manière la plus élégante. Merci Wesley!
Kiswanij
5

Il existe un petit programme sympa que vous pouvez utiliser pour rediriger la sortie vers un fichier et la console

some_command  ^|  TEE.BAT  [ -a ]  filename 

AquaAlex
la source
4

Ajoutez ces deux lignes en haut de votre fichier de commandes, tous les stdout et stderr après seront redirigés vers log.txt:

if not "%1"=="STDOUT_TO_FILE"  %0 STDOUT_TO_FILE %*  >log.txt 2>&1
shift /1
ilgitano
la source
Cela a fonctionné pour moi, merci. Des considérations spéciales où cela peut échouer? (par exemple, dépassement de la taille de sortie)
CCarlos
Salut, merci pour votre réponse! y a-t-il un moyen de le rediriger également sur la console?
Sandeep Singh le
3
@echo OFF
[your command] >> [Your log file name].txt

J'ai utilisé la commande ci-dessus dans mon fichier de commandes et cela fonctionne. Dans le fichier journal, il montre les résultats de ma commande.

Indra Permana
la source
0

Cela peut échouer dans le cas de caractères «toxiques» dans l'entrée. Considérer une entrée comme thisIsAnIn ^^^^ put est un bon moyen de comprendre ce qui se passe. Bien sûr, il existe une règle selon laquelle une chaîne d'entrée DOIT être entre guillemets doubles, mais j'ai le sentiment que cette règle n'est une règle valide que si la signification de l'entrée est un emplacement sur une partition NTFS (peut-être que c'est une règle pour les URL I suis pas sûr). Mais ce n'est pas une règle pour une chaîne d'entrée arbitraire bien sûr (c'est "une bonne pratique" mais vous ne pouvez pas compter avec).

Jan Antonin
la source
0

L'ajout des lignes suivantes au bas de votre fichier de commandes récupérera tout comme affiché dans la fenêtre CMD et l'exportera dans un fichier texte:

powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^a')
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^c')
powershell Get-Clipboard > MyLog.txt

Il effectue essentiellement une sélection de tout -> copier dans le presse - papiers -> coller dans un fichier texte .

GioVi
la source