Reindirizzamento dell'output dall'interno del file Batch


110

Sto creando un file batch con alcuni semplici comandi per raccogliere informazioni da un sistema. Il file batch contiene comandi per ottenere l'ora, le informazioni IP, gli utenti, ecc.

Ho assemblato tutti i comandi in un file batch e viene eseguito, ma vorrei che il file batch, una volta eseguito, restituisse i risultati in un file di testo (log). C'è un comando che posso aggiungere al batch che lo farebbe?

Tieni presente che non voglio eseguire il batch da cmd, quindi reindirizzare l'output; Voglio reindirizzare l'output dall'interno del batch, se possibile.

Risposte:


161

Il modo semplice e ingenuo che è lento perché apre e posiziona il puntatore del file su Fine file più volte.

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

Un modo migliore: più facile da scrivere e più veloce perché il file viene aperto e posizionato una sola volta.

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

Un altro modo buono e veloce che apre e posiziona il file solo una volta

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

:sub
command1
command2
...
commandN

Modifica 2020-04-17

Di tanto in tanto potresti voler scrivere ripetutamente su due o più file. Potresti anche volere messaggi diversi sullo schermo. È ancora possibile farlo in modo efficiente reindirizzando a handle non definiti all'esterno di un blocco o subroutine tra parentesi e quindi utilizzare la &notazione per fare riferimento ai file già aperti.

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

Ho scelto di utilizzare gli handle 9 e 8 in ordine inverso perché in questo modo è più probabile che eviti un potenziale reindirizzamento permanente a causa di un difetto di progettazione dell'implementazione del reindirizzamento Microsoft quando si eseguono reindirizzamenti multipli sullo stesso comando. È altamente improbabile, ma anche quell'approccio potrebbe esporre il bug se ci provi abbastanza. Se metti in scena il reindirizzamento, hai la garanzia di evitare il problema.

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

:sub
etc.

2
Adoro le soluzioni in cui posso impostarlo per il resto del file
Sam

3
Nota che la soluzione di chiamata cambia il tuo % 0 (in sub in questo caso) che può essere o meno quello che vuoi.
Jannes

1
@Jannes - Vero, ma puoi sempre ottenere informazioni sullo script batch in esecuzione se aggiungi un modificatore. Ad esempio, %~f0fornisce sempre il percorso completo allo script batch, anche se all'interno di una subroutine CALLed :.
dbenham

3
@ThariqNugrohotomo ->output.txt 2>&1
dbenham

2
@Moondra - questa è la sintassi batch standard per chiamare una subroutine etichettata all'interno dello stesso script. Eseguire cmd /?o help cmddalla riga di comando della console per la documentazione. Il trucco del terzo metodo è che il reindirizzamento su CALL si applica a tutti i comandi all'interno della subroutine CALLed.
dbenham


16

So che questo è un post più vecchio, ma qualcuno si imbatterà in esso in una ricerca su Google e sembra anche che alcune domande poste dall'OP nei commenti non siano state specificamente affrontate. Inoltre, per favore vacci piano con me poiché questa è la mia prima risposta pubblicata su SO. :)

Per reindirizzare l'output a un file utilizzando un nome di file generato dinamicamente, il mio approccio go-to (leggi: veloce e sporco) è la seconda soluzione offerta da @dbenham. Quindi, ad esempio, questo:

@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
)

Creerà un file come quello che vedi in questo screenshot del file nella directory di destinazione

Che conterrà questo output:

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

Inoltre, tieni presente che questa soluzione dipende dalle impostazioni locali, quindi fai attenzione a come / quando la usi.


Grazie questo è stato utile. Domanda veloce: c'è un motivo per cui stai usando .log vs .txt? Fa differenza?
Moondra

1
@ Moondra no, non lo fa. È solo semantica in questo caso. Questo non vuol dire che non ci siano applicazioni che richiedono / grep in base al tipo di file, quindi tieni presente se / come vengono utilizzati i tuoi file.
Anthony

9
echo some output >"your logfile"

o

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

dovrebbe riempire il conto.

Se vuoi APPENDl'output, usa >>invece di >. >inizierà un nuovo file di registro.


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

Penso che questo sia il modo più elegante. Grazie Wesley!
Kiswanij

5

C'è un piccolo programma interessante che puoi usare per reindirizzare l'output su un file e sulla console

some_command  ^|  TEE.BAT  [ -a ]  filename 


4

Aggiungi queste due linee nella parte superiore del tuo file batch, tutto lo stdout e lo stderr dopo verranno reindirizzati a log.txt:

if not "%1"=="STDOUT_TO_FILE"  %0 STDOUT_TO_FILE %*  >log.txt 2>&1
shift /1

Questo ha funzionato per me, grazie. Qualche considerazione speciale in cui questo potrebbe fallire? (es. overflow della dimensione dell'output)
CCarlos

Ciao, grazie per la tua risposta! c'è un modo per reindirizzarlo anche su console?
Sandeep Singh,

3
@echo OFF
[your command] >> [Your log file name].txt

Ho usato il comando sopra nel mio file batch e funziona. Nel file di registro, mostra i risultati del mio comando.


0

Ciò potrebbe non riuscire nel caso di caratteri "tossici" nell'input. Considerare un input come questoIsAnIn ^^^^ put è un buon modo per capire cosa sta succedendo. Sicuramente esiste una regola per cui una stringa di input DEVE essere racchiusa tra virgolette doppie, ma ho la sensazione che questa regola sia una regola valida solo se il significato dell'input è una posizione su una partizione NTFS (forse è una regola per gli URL I non sono sicuro). Ma ovviamente non è una regola per una stringa di input arbitraria (è "una buona pratica" ma non puoi contarci).


0

L'aggiunta delle seguenti righe nella parte inferiore del file batch acquisirà tutto esattamente come visualizzato nella finestra CMD ed esporterà in un file di testo:

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

Fondamentalmente esegue un seleziona tutto -> copia negli appunti -> incolla nel file di testo .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.