[Batch-file] Visualizzazione dell'output del prompt dei comandi di Windows e reindirizzamento a un file


Answers

Per espandere la risposta di davor , è possibile utilizzare PowerShell in questo modo:

powershell "dir | tee test.txt"

Se stai cercando di reindirizzare l'output di un exe nella directory corrente, devi usare .\ Sul nome del file, ad esempio:

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

Come posso eseguire un'applicazione della riga di comando nel prompt dei comandi di Windows e avere l'output sia visualizzato che reindirizzato su un file nello stesso momento?

Se, ad esempio, dovessi eseguire il comando dir > test.txt , ciò reindirizzerebbe l'output a un file chiamato test.txt senza visualizzare i risultati.

Come posso scrivere un comando per visualizzare l'output e reindirizzare l'output su un file nel prompt dei comandi di Windows, in modo simile al comando tee su Unix?




Controlla questo: wintee

Non c'è bisogno di cygwin.

Ho incontrato e segnalato alcuni problemi però.

Inoltre potresti controllare http://unxutils.sourceforge.net/ perché contiene tee (e non c'è bisogno di cygwin), ma http://unxutils.sourceforge.net/ attenzione che gli EOL di output sono simili a UNIX qui.

Ultimo, ma non meno importante, è che se hai PowerShell, potresti provare Tee-Object. Digitare get-help tee-object nella console di PowerShell per ulteriori informazioni.




Questo funziona, anche se è un po 'brutto:

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

È un po 'più flessibile di alcune delle altre soluzioni, in quanto funziona statement-by-statement in modo da poterlo usare anche per aggiungere. Lo uso abbastanza nei file batch per registrare e visualizzare i messaggi:

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

Sì, puoi semplicemente ripetere l'istruzione ECHO (una volta per lo schermo e la seconda volta reindirizzare al file di log), ma sembra altrettanto brutto ed è un po 'un problema di manutenzione. Almeno in questo modo non è necessario apportare modifiche ai messaggi in due punti.

Si noti che _ è solo un breve nome file, quindi è necessario assicurarsi di eliminarlo alla fine del file batch (se si sta utilizzando un file batch).




Un'alternativa è quella di aggiungere stdout a stderr all'interno del tuo programma:

in java:

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

Quindi, nel file batch dos: java program > log.txt

Lo stdout andrà al file di log e lo stderr (stessi dati) verrà mostrato sulla console.




@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

Ciò creerà un file di registro con il datetime corrente e le linee della console potranno essere utilizzate durante il processo




Sono d'accordo con Brian Rasmussen, la porta unxutils è il modo più semplice per farlo. Nella sezione File batch delle sue pagine di scripting, Rob van der Woude fornisce una grande quantità di informazioni sull'uso dei comandi MS-DOS e CMD. Ho pensato che potrebbe avere una soluzione nativa al tuo problema e dopo aver scavato da queste parti ho trovato TEE.BAT , che sembra essere proprio questo, un'implementazione in linguaggio batch di MS-DOS del tee. È un file batch piuttosto complesso e la mia inclinazione sarebbe comunque quella di utilizzare la porta unxutils.




Una semplice applicazione per console C # potrebbe fare il trucco:

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

Per usarlo basta inserire il comando source nel programma e fornire il percorso di tutti i file su cui si desidera duplicare l'output. Per esempio:

dir | CopyToFiles files1.txt files2.txt 

Visualizzerà i risultati di dir e memorizzerà i risultati sia in files1.txt che files2.txt.

Si noti che non c'è molto (nulla!) In termini di gestione degli errori di cui sopra, e il supporto di più file potrebbe non essere effettivamente richiesto.




Se hai cygwin nel tuo percorso di ambiente Windows puoi usare:

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



Come posso visualizzare e reindirizzare l'output su un file. Supponiamo che se utilizzo il comando dos, dir> test.txt, questo comando reindirizzerà l'output sul file test.txt senza visualizzare i risultati. come scrivere un comando per visualizzare l'output e reindirizzare l'output su un file utilizzando DOS, prompt dei comandi di Windows, non in UNIX / LINUX.

È possibile trovare utili questi comandi in biterscripting ( http://www.biterscripting.com ).

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.



Questa è una variazione rispetto a una answer precedente di MTS, tuttavia aggiunge alcune funzionalità che potrebbero essere utili ad altri. Ecco il metodo che ho usato:

  • Un comando è impostato come variabile, che può essere utilizzato in un secondo momento nel codice, per l'output nella finestra di comando e aggiunto a un file di registro, utilizzando set _Temp_Msg_Cmd=
    • il comando è stato redirection con il carattere carota ^ modo che i comandi non vengano valutati inizialmente
  • Viene creato un file temporaneo con un nome file simile al file batch da eseguire chiamato %~n0_temp.txt che utilizza la sintassi dell'estensione del parametro della riga di comando %~n0 per ottenere il nome del file batch.
  • L'output viene aggiunto a un file di registro separato %~n0_log.txt

Ecco la sequenza di comandi:

  1. I messaggi di output e di errore vengono inviati al file temporaneo ^> %~n0_temp.txt 2^>^&1
  2. Il contenuto del file temporaneo è quindi entrambi:
    • aggiunto al file di registro ^& type %~n0_temp.txt ^>^> %~n0_log.txt
    • ^& type %~n0_temp.txt alla finestra di comando ^& type %~n0_temp.txt
  3. Il file temporaneo con il messaggio viene cancellato ^& del /Q /F %~n0_temp.txt

Ecco l'esempio:

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

In questo modo, il comando può essere semplicemente aggiunto dopo i comandi successivi in ​​un file batch che sembra molto più pulito:

echo test message %_Temp_Msg_Cmd%

Questo può essere aggiunto anche alla fine di altri comandi. Per quanto posso dire funzionerà quando i messaggi hanno più linee. Ad esempio il seguente comando emette due righe se c'è un messaggio di errore:

net use M: /D /Y %_Temp_Msg_Cmd%




Stavo anche cercando la stessa soluzione, dopo un piccolo tentativo, sono riuscito a farlo in Prompt dei comandi. Ecco la mia soluzione:

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

Cattura anche qualsiasi comando PAUSE.




Installo perl sulla maggior parte delle mie macchine quindi una risposta usando 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 o dir | perl tee.pl dir.bat

grezzo e non testato.




Qualcosa di simile dovrebbe fare quello che ti serve?

%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