Wyświetlanie wyniku wiersza polecenia systemu Windows i przekierowanie go do pliku

371

Jak mogę uruchomić aplikację wiersza polecenia w wierszu polecenia systemu Windows, aby dane wyjściowe były jednocześnie wyświetlane i przekierowywane do pliku?

Jeśli na przykład miałbym uruchomić polecenie dir > test.txt, przekierowałoby to wyjście do pliku wywoływanego test.txtbez wyświetlania wyników.

Jak napisać polecenie, aby wyświetlić dane wyjściowe i przekierować dane wyjściowe do pliku w wierszu polecenia systemu Windows, podobnie jak teepolecenie w systemie Unix?

Edward Thomson
źródło
63
I proszę, przestań nazywać to MSDOS! Podobieństwa między cmd.exe a braindead command.com są minimalne i maleją.
paxdiablo
Żadne z tych nie działa, jeśli ktoś ma aplikację konsolową ładującą bibliotekę DLL, która wyświetla tekst. Główny tekst aplikacji zostaje przekierowany do pliku, ale dane wyjściowe z biblioteki dll nie są wyświetlane w oknie konsoli i nadal są wyświetlane. Nie znalazłem żadnego sposobu na przechwycenie tekstu z biblioteki dll.
Brian Reinhold
1
nadal można po prostu
potokować
Co jeśli korzystam z narzędzia wiersza polecenia i chcę przekierować dane wyjściowe do pliku w dokładnie takim samym formacie, jak wyświetlany na ekranie, użyłem youtube-dl do wyodrębnienia linków i mogłem przekierować dane wyjściowe do pliku txt, ale nie jest on sformatowany jako pojawi się monit, w pliku pojawi się jako pojedynczy wiersz.
beastboy

Odpowiedzi:

153

Aby rozwinąć odpowiedź davor , możesz użyć programu PowerShell w następujący sposób:

powershell "dir | tee test.txt"

Jeśli próbujesz przekierować wyjście exe w bieżącym katalogu, musisz użyć .\nazwy pliku, np .:

powershell ".\something.exe | tee test.txt"
Saxon Druce
źródło
8
To jest najbliższa odpowiedź: działa przy domyślnej instalacji, ponieważ PS jest już dostępny na większości komputerów, a zwłaszcza serwerów.
Stoleg
1
To najlepsza odpowiedź! Prosty i działa „po wyjęciu z pudełka”
Josh Werts
3
JAK TO :) w każdym razie {powershell "ping -n 10 localhost | tee test.txt"}
pokazałby
4
Zauważ, że dirw PowerShell jest alias, do Get-ChildItemktórego nie przypomina wewnętrznego dirpolecenia cmd . Potrzebujesz, powershell "cmd /c dir | tee test.txt"jeśli chcesz wersję wewnętrzną cmd
phuclv
8
aby zobaczyć wszystkie dane wyjściowe, nie zapomnij przekierować STDERR do STDOUT za pomocą 2>&1, na przykładnode 2>&1 | tee debug_log.txt
Zhe Hu
132

Udało mi się znaleźć rozwiązanie / obejście przekierowywania danych wyjściowych do pliku, a następnie do konsoli:

dir > a.txt | type a.txt

gdzie dir jest poleceniem, do którego wyjścia należy przekierować, a.txt plik, w którym należy zapisać dane wyjściowe.

NSPKUWCExi2pr8wVoGNk
źródło
100
Spełnia to odpowiedź, ale wysyła dane po zakończeniu polecenia dir, a nie po wygenerowaniu danych.
Leigh Riffel,
10
zadziała, ale utkniesz, jeśli polecenie poczeka na wejście ze standardowego wejścia.
Vitim.us 18.04.13
5
Podoba mi się ta prosta odpowiedź! Odkryłem, że &zamiast |wyjścia jest potrzebne wyjście niektórych poleceń, takich jak pinglub7z.exe
Wes Larson
Nie działa zamiast poleceń interaktywnych dir. Przykład: chkdsk /f c: > c:\Temp.txt | c:\Temp.txt. Plik raportu systemowego jest blokowany przez inny proces.
Sopalajo de Arrierez
4
@lii re: handle output to stderr- dodaj 2>&1przekierowanie więc jest tak: dir 2>&1 > a.txt & type a.txta ty powinny mieć stderr miesza się z stdout.
Jesse Chisholm
97

Jest port Win32 teepolecenia Unix , który robi dokładnie to. Zobacz http://unxutils.sourceforge.net/ lub http://getgnuwin32.sourceforge.net/

Brian Rasmussen
źródło
17
Łącze wskazuje implementację systemu Windows w systemie Unix, więc działa w systemie Windows.
Brian Rasmussen
3
Tak, głosowanie nad odpowiedzią i komentarzem. Wolałbym CygWin, ponieważ ma wszystko, ale niektórzy ludzie wolą narzędzia inne niż DLL, które mogą wybierać.
paxdiablo
3
Wiele narzędzi uniksowych jest także przenoszonych przez projekt GnuWin32 , patrz gnuwin32.sourceforge.net .
VladV
2
UnxUtils został ostatnio zaktualizowany w 2003 roku; GnuWin32 jest nieco bardziej aktualny.
quack quixote
9
Jeśli podobnie jak ja teemiałeś problem ze znalezieniem pakietu GnuWin32, znajdziesz go w gnuwin32.sourceforge.net/packages/coreutils.htm .
Nigel Touch
49

Sprawdź to: wintee

Nie potrzebujesz cygwina.

Spotkałem się i zgłosiłem kilka problemów.

Możesz także sprawdzić unxutils, ponieważ zawiera tee (i nie potrzebujesz cygwina), ale uważaj, że wyjściowe EOL są tutaj podobne do UNIX-a.

Wreszcie, jeśli masz PowerShell, możesz wypróbować Tee-Object. Wpisz get-help tee-objectkonsolę PowerShell, aby uzyskać więcej informacji.

Davor Josipovic
źródło
4
Dlaczego głosowanie w dół? 95% odpowiedzi ma jedną wspólną cechę: dane wyjściowe są przekierowywane dopiero po zakończeniu pierwszego polecenia: przeczytaj komentarze. Narzędzie UNIX teegeneruje dane w czasie rzeczywistym. wteema tę samą funkcjonalność. Jeśli nie masz nic przeciwko błędom, będzie dobrze.
Davor Josipovic
To jedyne rozwiązanie, które działa dla mnie, bez Powershell> 4.0. Kciuki w górę!
Alex
46

@ tori3852

znalazłem to

dir > a.txt | type a.txt

nie działało (tylko kilka pierwszych wierszy listowania katalogów - podejrzewam, że rozwidla się jakiś proces, a druga część, polecenie „typ” zakończyło się przed zakończeniem listingu?), więc zamiast tego użyłem:

dir > z.txt && type z.txt

który zrobił - sekwencyjne polecenia, jedno wykonuje się przed drugim uruchomieniem.

Andy Welch
źródło
17
Powinieneś użyć &zamiast, &&jeśli chcesz się upewnić, że typepolecenie zostało wykonane, nawet jeśli dirpolecenie się nie powiedzie. Jest to przydatne, gdy w twoim poleceniu wystąpił jakiś błąd i nadal chcesz zobaczyć plik dziennika na konsoli. Zobacz artykuł Microsoft na ten temat . Problem %errorlevel%polega jednak na ustawieniu poziomu błędu na type(który wynosiłby 0).
ADTC
25

Niestety nie ma czegoś takiego.

Aplikacje konsoli Windows mają tylko jeden uchwyt wyjściowy. (Cóż, są dwa STDOUT, STDERRale to nie ma znaczenia). >Przekierowuje wyjście normalnie zapisywane do uchwytu konsoli do uchwytu pliku.

Jeśli chcesz mieć pewnego rodzaju multipleksowanie, musisz użyć zewnętrznej aplikacji, na którą możesz przekierować wyjście. Ta aplikacja może następnie ponownie zapisać plik i konsolę.

Daniel Rikowski
źródło
3
teena * nix to także osobna aplikacja, a nie jakieś przekierowanie na powłokę
phuclv
22

Prosta aplikacja na konsolę C # załatwi sprawę:

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

Aby tego użyć, po prostu potokuj polecenie źródłowe do programu i podaj ścieżkę do plików, które chcesz zduplikować. Na przykład:

dir | CopyToFiles files1.txt files2.txt 

Wyświetli wyniki dir, a także zapisze wyniki zarówno w plikach1.txt, jak i plikach2.txt.

Należy pamiętać, że powyższy sposób obsługi błędów nie ma wiele (nic!), A obsługa wielu plików może nie być wymagana.

Richard
źródło
5
Hmm, pobierz tee / cygwin za darmo lub kup MSVS z moją ciężko zarobioną gotówką na tak żałośnie mały program jak ten? To trudne :-)
paxdiablo
19
Nie potrzebujesz programu Visual Studio, aby to skompilować, narzędzia wiersza poleceń są w rzeczywistości darmowe. po prostu google „.net sdk download” dla linku (bezpośredni link wydaje się zmieniać, ale google zawsze działa).
Kris,
13
Visual Studio Express jest również bezpłatny, ale nadal używałbym do tego tee.
Brian Rasmussen
7
Cygwin jest trudny do zainstalowania. Głosujcie, bo tego właśnie szukałem.
Samaursa
1
Nie wydaje mi się, aby to wyświetlało się w konsoli i jednocześnie pliki, prawda?
mjaggard,
20

To działa, choć jest trochę brzydkie:

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

Jest nieco bardziej elastyczny niż niektóre inne rozwiązania, ponieważ działa instrukcja po instrukcji, dzięki czemu można go również używać do dołączania. Używam tego dość często w plikach wsadowych do rejestrowania i wyświetlania komunikatów:

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

Tak, możesz po prostu powtórzyć instrukcję ECHO (raz na ekranie i po raz drugi przekierowanie do pliku dziennika), ale wygląda to tak samo źle i jest to trochę problem z konserwacją. Przynajmniej w ten sposób nie musisz wprowadzać zmian w wiadomościach w dwóch miejscach.

Zauważ, że _ to tylko krótka nazwa pliku, więc musisz ją usunąć na końcu pliku wsadowego (jeśli używasz pliku wsadowego).

MTS
źródło
2
Jest to przydatne tylko wtedy, gdy chcesz wyświetlić zawartość PO uruchomieniu procesu. I to nie jest trudny problem do rozwiązania.
Christopher Painter
1
Tak, myślę, że rozwiązuje to nieco inny problem niż ten, o który pytał oryginalny plakat.
MTS
1
+1 Tak zawsze to robiłem. Uważam, że jest to poprawna odpowiedź na pierwotne pytanie i powinna zostać oznaczona jako tak. Sztuczka, jak sugeruje @MTS, polega na tym, że faktycznie piszesz do dwóch plików: jednego, który jest tworzony dla każdego polecenia / wiersza (stąd pojedynczy „>”, który zastępuje się za każdym razem), a następnie wpisujesz ten wiersz na ekranie ( typ ), a na koniec wpisujesz go ponownie i przekierowujesz dane wyjściowe, całe DODATKOWE, do pliku dziennika za pomocą „>>”. Tak robiłem od lat, chociaż uwielbiam prosty plik tymczasowy. Zawsze robiłem „tmp.txt” lub coś w tym stylu. Tak, usuń go później.
eduncan911
To dobre podejście, ale miałem problemy z błędami, które nie zostały wychwycone. typeNaprawiono to, umieszczając polecenia w osobnych wierszach (w podprogramie).
Nate Cook
Właśnie tego potrzebowałem do mojej aplikacji.
Alan
16

mtee to małe narzędzie, które działa bardzo dobrze w tym celu. Jest bezpłatny, źródło jest otwarte i po prostu działa.

Można go znaleźć na stronie http://www.commandline.co.uk .

Używana w pliku wsadowym do wyświetlania danych wyjściowych ORAZ utworzenia pliku dziennika jednocześnie, składnia wygląda następująco:

    someprocess | mtee /+ mylogfile.txt

Gdzie / + oznacza dołączenie wyniku.

Zakłada się, że skopiowałeś mtee do folderu, który znajduje się w PATH, oczywiście.

znak
źródło
1
Wydaje się, że to czeka, aż dane wyjściowe zostaną zakończone, również przed wysłaniem do pliku lub konsoli.
mellamokb
14

Chciałbym trochę rozwinąć doskonałą odpowiedź Saxona Druce'a .

Jak już wspomniano, możesz przekierować wyjście pliku wykonywalnego w bieżącym katalogu w następujący sposób:

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

Jednak tylko loguje się stdoutdo test.txt. Nie rejestruje się również stderr.

Oczywistym rozwiązaniem byłoby użycie czegoś takiego:

powershell ".\something.exe 2>&1 | tee test.txt"

Jednak to nie zadziała dla wszystkich something.exes. Niektórzy something.exes zinterpretują to 2>&1jako argument i zawiodą. Prawidłowe rozwiązanie to zamiast tego mieć apostrofy tylko wokół something.exeprzełączników i argumentów, tak jak poniżej:

powershell ".\something.exe --switch1 --switch2 … arg1 arg2 …" 2>&1 | tee test.txt
ア リ ス タ ー
źródło
Próbowałem tego podczas budowania pyqt5.7 na Windows 10, jest dość powolny, wyjście konsoli nie jest w czasie rzeczywistym, może jest buforowane? plik dziennika wygląda jednak poprawnie
Shuman
3
Wszystko to jest całkowicie błędne. Dla mnie to w ogóle nie działa. Ostatnie polecenie podaje 'tee' is not recognized as an internal or external commandz oczywistych powodów. Z 2>&1wewnątrz cmd linii dowolne wyjście na stderr powoduje błędy z PowerShell.
Pavel P
Może być odniesieniem do polecenia cmdlet Tee-Object PowerShell - technet.microsoft.com/en-us/library/ee177014.aspx
Bernd
9

Zgadzam się z Brianem Rasmussenem, że port unxutils jest najłatwiejszym sposobem na zrobienie tego. W sekcji Pliki wsadowe swoich stron skryptów Rob van der Woude zawiera wiele informacji na temat korzystania z poleceń MS-DOS i CMD. Pomyślałem, że może on mieć natywne rozwiązanie twojego problemu i po tym, jak się tam przekopałem , znalazłem TEE.BAT , który wydaje się być właśnie implementacją tee w MS-DOS. Jest to dość skomplikowany plik wsadowy i nadal chciałbym używać portu unxutils.

Steve Crane
źródło
Ta tee.bat wygląda ładnie. Mam nadzieję, że OP to sprawdza.
Jay
10
Zauważ, że użycie TEE.BAT wyświetli się po zakończeniu polecenia, podobnie jak przykład „dir> a.txt | type a.txt” opublikowany w pobliżu.
adzm
8

Jeśli masz cygwin na ścieżce środowiska Windows, możesz użyć:

 dir > a.txt | tail -f a.txt
jkdba
źródło
7
Jeśli zamierzasz użyć Cygwin, jest on wyposażony w koszulkę.
Pan Llama,
7

dir 1>a.txt 2>&1 | type a.txt

Pomoże to przekierować STDOUT i STDERR

rashok
źródło
To nie działa Próbowałem tego użyć do uruchomienia pliku run.bat JBoss, który dusi się podczas uruchamiania, a serwer zawiesza się. Istnieją problemy z tą metodą ...
djangofan,
@raja ashok, nie działa dla mnie. Próbowałem python.exe 1> plik.txt 2> i 1 | wpisz file.txt
neo
4

Wiem, że to bardzo stary temat, ale we wcześniejszych odpowiedziach nie ma pełnej implementacji trójnika w czasie rzeczywistym napisanego Batch. Moje rozwiązanie poniżej to hybrydowy skrypt Batch-JScript, który używa sekcji JScript tylko w celu uzyskania danych wyjściowych z polecenia potokowego, ale przetwarzanie danych odbywa się w sekcji Batch. Takie podejście ma tę zaletę, że każdy programista Batch może modyfikować ten program, aby dopasować go do określonych potrzeb. Ten program również poprawnie przetwarza dane wyjściowe polecenia CLS wygenerowane przez inne pliki wsadowe, tzn. Czyści ekran po wykryciu danych wyjściowych polecenia CLS.

@if (@CodeSection == @Batch) @then


@echo off
setlocal EnableDelayedExpansion

rem APATee.bat: Asynchronous (real time) Tee program, Batch-JScript hybrid version
rem Antonio Perez Ayala

rem The advantage of this program is that the data management is written in Batch code,
rem so any Batch programmer may modify it to fit their own needs.
rem As an example of this feature, CLS command is correctly managed

if "%~1" equ "" (
   echo Duplicate the Stdout output of a command in the screen and a disk file
   echo/
   echo anyCommand ^| APATee teeFile.txt [/A]
   echo/
   echo If /A switch is given, anyCommand output is *appended* to teeFile.txt
   goto :EOF
)

if "%2" equ ":TeeProcess" goto TeeProcess

rem Get the output of CLS command
for /F %%a in ('cls') do set "cls=%%a"

rem If /A switch is not provided, delete the file that receives Tee output
if /I "%~2" neq "/A" if exist %1 del %1

rem Create the semaphore-signal file and start the asynchronous Tee process
echo X > Flag.out
if exist Flag.in del Flag.in
Cscript //nologo //E:JScript "%~F0" | "%~F0" %1 :TeeProcess
del Flag.out
goto :EOF

:TeeProcess
   rem Wait for "Data Available" signal
   if not exist Flag.in goto TeeProcess
   rem Read the line sent by JScript section
   set line=
   set /P line=
   rem Set "Data Read" acknowledgement
   ren Flag.in Flag.out
   rem Check for the standard "End Of piped File" mark
   if "!line!" equ ":_EOF_:" exit /B
   rem Correctly manage CLS command
   if "!line:~0,1!" equ "!cls!" (
      cls
      set "line=!line:~1!"
   )
   rem Duplicate the line in Stdout and the Tee output file
   echo(!line!
   echo(!line!>> %1
goto TeeProcess


@end


// JScript section

var fso = new ActiveXObject("Scripting.FileSystemObject");
// Process all lines of Stdin
while ( ! WScript.Stdin.AtEndOfStream ) {
   // Read the next line from Stdin
   var line = WScript.Stdin.ReadLine();
   // Wait for "Data Read" acknowledgement
   while ( ! fso.FileExists("Flag.out") ) {
      WScript.Sleep(10);
   }
   // Send the line to Batch section
   WScript.Stdout.WriteLine(line);
   // Set "Data Available" signal
   fso.MoveFile("Flag.out", "Flag.in");
}
// Wait for last "Data Read" acknowledgement
while ( ! fso.FileExists("Flag.out") ) {
      WScript.Sleep(10);
}
// Send the standard "End Of piped File" mark
WScript.Stdout.WriteLine(":_EOF_:");
fso.MoveFile("Flag.out", "Flag.in");
Aacini
źródło
W jakikolwiek sposób może to uchwycić wyjście stderr? Mam irytującego exe, który wypisuje wszystko w standardowym strumieniu błędów (tj. Aby normalnie file.exe 2>output.txt
wypisać
Rozgryzłem to. Możesz to zrobić, korzystając z file.exe 2>&1|tee.bat
poniższego opisu
4

Szukałem również tego samego rozwiązania, po krótkiej próbie udało mi się to osiągnąć w wierszu polecenia. Oto moje rozwiązanie:

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

Przechwytuje nawet dowolne polecenie PAUZA.

Koder101
źródło
3

Oto próbka tego, czego użyłem na podstawie jednej z pozostałych odpowiedzi

@echo off
REM SOME CODE
set __ERROR_LOG=c:\errors.txt
REM set __IPADDRESS=x.x.x.x

REM Test a variable
if not defined __IPADDRESS (
     REM Call function with some data and terminate
     call :TEE %DATE%,%TIME%,IP ADDRESS IS NOT DEFINED
     goto :EOF
)

REM If test happens to be successful, TEE out a message and end script.
call :TEE Script Ended Successful
goto :EOF


REM THE TEE FUNCTION
:TEE
for /f "tokens=*" %%Z in ("%*") do (
     >  CON ECHO.%%Z
     >> "%__ERROR_LOG%" ECHO.%%Z
     goto :EOF
)
Ed Radke
źródło
3

Coś takiego powinno zrobić to, czego potrzebujesz?

%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
Richard K.
źródło
Prawie, ale nie wyświetla się jednocześnie - jeśli masz długo trwające zadanie, przez długi czas nie otrzymasz żadnych wyników.
JustAMartin,
3

wyślij dane wyjściowe do konsoli, dołącz do dziennika konsoli, usuń dane wyjściowe z bieżącego polecenia

dir  >> usb-create.1 && type usb-create.1 >> usb-create.log | type usb-create.1 && del usb-create.1
Dennis
źródło
8
chcesz wyjaśnić, co tu się dzieje?
John Demetriou,
2

Jest to odmiana poprzedniej odpowiedzi MTS, jednak dodaje ona niektórych funkcji, które mogą być przydatne dla innych. Oto metoda, której użyłem:

  • Polecenie jest ustawione jako zmienna, z której można później korzystać w całym kodzie, aby wyświetlać dane w oknie poleceń i dołączać do pliku dziennika za pomocą set _Temp_Msg_Cmd=
    • polecenie uniknęło przekierowania za pomocą ^znaku marchewki, więc polecenia nie są początkowo oceniane
  • Tworzony jest plik tymczasowy o nazwie podobnej do uruchamianego pliku wsadowego, %~n0_temp.txtktóry używa składni rozszerzenia parametru wiersza polecenia, %~n0 aby uzyskać nazwę pliku wsadowego.
  • Dane wyjściowe są dołączane do osobnego pliku dziennika %~n0_log.txt

Oto sekwencja poleceń:

  1. Dane wyjściowe i komunikaty o błędach są wysyłane do pliku tymczasowego ^> %~n0_temp.txt 2^>^&1
  2. Zawartość pliku tymczasowego jest wtedy zarówno:
    • dołączony do pliku dziennika ^& type %~n0_temp.txt ^>^> %~n0_log.txt
    • wyjście do okna poleceń ^& type %~n0_temp.txt
  3. Plik tymczasowy z wiadomością zostanie usunięty ^& del /Q /F %~n0_temp.txt

Oto przykład:

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

W ten sposób polecenie można po prostu dołączyć po późniejszych poleceniach do pliku wsadowego, który wygląda na znacznie czystszy:

echo test message %_Temp_Msg_Cmd%

Można to również dodać na końcu innych poleceń. O ile mogę stwierdzić, będzie działać, gdy wiadomości mają wiele linii. Na przykład następujące polecenie wyświetla dwa wiersze, jeśli pojawia się komunikat o błędzie:

net use M: /D /Y %_Temp_Msg_Cmd%

ClearBlueSky85
źródło
1
@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

Spowoduje to utworzenie pliku dziennika z bieżącą datą i możesz konsolować wiersze konsoli podczas procesu

7thSphere
źródło
11
czy nie wywołujesz dwukrotnie tego samego programu?
elcool
1

Korzystam z podprogramu wsadowego z instrukcją „for”, aby uzyskać dane wyjściowe polecenia po jednym wierszu, i oba zapisują ten wiersz do pliku i wysyłają go do konsoli.

@echo off
set logfile=test.log

call :ExecuteAndTee dir C:\Program Files

Exit /B 0

:ExecuteAndTee
setlocal enabledelayedexpansion
echo Executing '%*'
  for /f "delims=" %%a in ('%* 2^>^&1') do (echo.%%a & echo.%%a>>%logfile%)
endlocal
Exit /B 0
Cody Barnes
źródło
Robię to samo, gdy próbuję przechwycić dane wyjściowe polecenia (IE wstawiam je do for), ale potem po prostu wywołuję moją standardową podfunkcję, aby wyświetlić echo ekranu i napisać dziennik, ponieważ używam go w całym skrypcie zamiast używania echa . Nie jestem pewien, dlaczego otrzymało to opinię od innych, więc głosowałem za nią.
Ben Personick
1

Jeśli korzystasz z interfejsu CLI, skorzystaj z pętli FOR, aby „zrobić” cokolwiek chcesz:

for /F "delims=" %a in ('dir') do @echo %a && echo %a >> output.txt

Świetny zasób na Windows CMD dla pętli: https://ss64.com/nt/for_cmd.html Kluczem tutaj jest ustawienie ograniczników (delimów), które zerwałyby każdą linię wyjścia, do zera. W ten sposób nie zepsuje się domyślnej białej spacji. % A to dowolna litera, ale jest używana w sekcji „do”, aby ... cóż ... zrobić coś ze znakami, które zostały przeanalizowane w każdym wierszu. W takim przypadku możemy użyć znaków ampersands (&&) do wykonania drugiego polecenia echa w celu utworzenia lub dołączenia (>>) do wybranego przez nas pliku. Bezpieczniej jest zachować tę kolejność poleceń DO na wypadek, gdyby wystąpił problem z zapisaniem pliku, przynajmniej dostaniemy echo do konsoli. Znak at (@) przed pierwszym echem powstrzymuje konsolę przed wyświetlaniem samego polecenia echo, a zamiast tego wyświetla wynik polecenia, które ma wyświetlać znaki w% a. W przeciwnym razie zobaczysz:

echo Wolumin na dysku [x] to Windows
Wolumin na dysku [x] to Windows

AKTUALIZACJA: / F pomija puste linie i jedyną poprawką jest wstępne filtrowanie wyniku, dodając znak do każdej linii (być może z numerami linii za pomocą polecenia find). Rozwiązanie tego w CLI nie jest szybkie ani ładne. Nie dodałem także STDERR, więc tutaj również są błędy:

for /F "delims=" %a in ('dir 2^>^&1') do @echo %a & echo %a >> output.txt

Przekierowywanie komunikatów o błędach

Kreski (^) służą do ucieczki przed symbolami po nich, ponieważ polecenie jest ciągiem, który jest interpretowany, w przeciwieństwie do tego, wprowadzając go bezpośrednio w wierszu polecenia.

Musiałem zapytać
źródło
1

Podobnie jak unix.

dir | tee a.txt

Działa w systemie Windows XP, wymaga mksntzainstalowania.

Wyświetla się w monicie, a także dołącza się do pliku.

użytkownik2346926
źródło
0

Poniższe informacje pomagają, jeśli chcesz naprawdę zobaczyć coś na ekranie - nawet jeśli plik wsadowy został przekierowany do pliku. Urządzenie CON może być również używane, jeśli zostanie przekierowane do pliku

Przykład:

ECHO first line on normal stdout. maybe redirected
ECHO second line on normal stdout again. maybe redirected
ECHO third line is to ask the user. not redirected  >CON
ECHO fourth line on normal stdout again. maybe redirected

Zobacz także dobry opis przekierowania: http://www.p-dd.com/chapter7-page14.html


źródło
0

Jak wyświetlić i przekierować dane wyjściowe do pliku. Załóżmy, że jeśli użyję polecenia dos, katalog> test.txt, to polecenie przekieruje dane wyjściowe do pliku test.txt bez wyświetlania wyników. jak napisać polecenie, aby wyświetlić dane wyjściowe i przekierować dane wyjściowe do pliku przy użyciu DOS, tj. wiersz polecenia systemu Windows, a nie w UNIX / LINUX.

Przydatne mogą być te polecenia w skryptowaniu bitów ( 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.
PO POŁUDNIU
źródło
0

Działa to w czasie rzeczywistym, ale jest też trochę brzydkie, a wydajność jest niska. Niezbyt dobrze przetestowany:

@echo off
cls
SET MYCOMMAND=dir /B
ECHO File called 'test.bat' > out.txt
for /f "usebackq delims=" %%I in (`%MYCOMMAND%`) do (
  ECHO %%I
  ECHO %%I >> out.txt
) 
pause
djangofan
źródło
6
Nie, to nie jest czas rzeczywisty, czeka na %MYCOMMAND%zakończenie i w wielu przypadkach kończy się niepowodzeniem. Pomija ono puste linie, linie zaczynające się ;nie powiedzie się z treścią jak <space>/<TAB>, ON, OFFlub /?. Ale reszta może czasem działać :-)
jeb
0

Alternatywą jest wprowadzenie standardowego do standardowego w swoim programie:

w java:

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

Następnie w pliku wsadowym dos: java program > log.txt

Stdout przejdzie do pliku dziennika, a stderr (te same dane) pojawi się na konsoli.

Koordynator
źródło
0

Instaluję perla na większości moich maszyn, więc odpowiedź za pomocą perla: 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;

reż | perl tee.pl lub reż | perl tee.pl reż. bat

surowy i nieprzetestowany.

DannyK
źródło
0

Inną odmianą jest podzielenie potoku, a następnie przekierowanie wyjścia według własnego uznania.

    @echo off
    for /f "tokens=1,* delims=:" %%P in ('findstr /n "^"') do (
      echo(%%Q
      echo(%%Q>&3
    )
    @exit/b %errorlevel%

Zapisz powyższe w pliku .bat. Dzieli również tekst na strumieniu plików 1 na strumień plików 3, który można przekierować w razie potrzeby. W poniższych przykładach nazwałem powyższy skrypt splitPipe.bat ...

    dir | splitPipe.bat  1>con  2>&1  3>my_stdout.log

    splitPipe.bat 2>nul < somefile.txt
użytkownik3726414
źródło
-1
  1. https://cygwin.com/install
  2. Kliknij link „setup-x86_.exe”
  3. Uruchom instalatora
  4. Na ~ 2. stronie wybierz „dublowanie”, z którego chcesz pobrać (szukałem domeny .edu)
  5. Powiedziałem ok do standardowych opcji
  6. Cygwin szybko zakończył instalację
  7. Otwórz cmd
  8. Wpisz c:\cygwin64\bin\script.exei wpisz
  9. Wpisz cmdi wpisz
  10. Uruchom swój program
  11. Wpisz exiti wprowadź (wychodzi z Cygwin's cmd.exe)
  12. Wpisz exiti wprowadź (wychodzi z Cygwin's script.exe)
  13. Zobacz wyjście ekranu programu w pliku tekstowym o nazwie „maszynopis”
Joseph Hansen
źródło