Przekieruj stdout i stderr systemu Windows do jednego pliku

688

Próbuję przekierować wszystkie dane wyjściowe (stdout + stderr) systemu DOS polecenia do jednego pliku:

C:\>dir 1> a.txt 2> a.txt
The process cannot access the file because it is being used by another process.

Czy to możliwe, czy powinienem po prostu przekierować do dwóch osobnych plików?

ripper234
źródło
14
TechNet: Korzystanie z operatorów przekierowywania poleceń (odpowiada to lepiej niż którakolwiek z odpowiedzi tutaj).
Martin Prikryl
1
2> i 1, ponieważ nie można ponownie otworzyć tego samego pliku
Luke

Odpowiedzi:

1090

Chcesz:

dir > a.txt 2>&1

Składnia 2>&1przekieruje 2(stderr) na 1(stdout). Możesz także ukryć wiadomości, przekierowując na NUL, więcej wyjaśnień i przykładów na MSDN .

Anders Lindahl
źródło
32
dzięki za to, nie wiedziałem, że ta składnia powłoki unixowej działa również dla DOS!
Chaindriver
20
jest to świetne do ukrywania całej produkcji .. net stop w3svc >NUL 2>&1.. dzięki!
wasatchwizard
3
@wasatchwizard Ithink Miałem z tym problem, ale> NUL 2> NUL działało dobrze
FrinkTheBrave
13
Jeśli istnieje Uchwyt, nie może być odstępu między Uchwytem (tj. 2) a operatorem przekierowania (tj.>). Dlatego 2> 2.txtdziała (lub 2> &1) 2 > 2.txtnie; 2 > &1nie.
Czerwony groszek
9
Tak bardzo kocham. „Ugh, ten mały jednorazowy problem zajmie godzinę.” Napisanie tego komentarza zajęło mi więcej czasu niż znalezienie tej odpowiedzi.
Brandon
195

Anders Lindahl odpowiedź jest poprawna, ale należy zauważyć, że jeśli przekierowanie stdout do pliku i chcesz przekierować stderr, jak również wtedy należy upewnić się, że 2>&1jest określona PO z 1>przekierowaniem, inaczej nie zadziała.

REM *** WARNING: THIS WILL NOT REDIRECT STDERR TO STDOUT ****
dir 2>&1 > a.txt
DelboyJay
źródło
10
PO to, co kosztowało mnie godziny, aby dowiedzieć się, co jest nie tak DelboyJay! Dziękuję Ci!
Nam G VU,
4
Czy gdziekolwiek wyjaśniono, dlaczego umieszczenie 2> i 1 przed 1> nie osiągnie zamierzonego efektu? Podejrzewam, że ma to związek ze sposobem, w jaki „cmd” analizuje polecenia, które nadają dwa różne znaczenia w zależności od kolejności, w której określasz przekierowanie. Ale reguły semantyczne są wszędzie udokumentowane, ponieważ uważam, że warto się tego nauczyć, ponieważ może to zmarnować wiele godzin.
igbgotiz
12
@igbgotiz 2> & 1 oznacza „przekieruj strumień 2 do strumienia 1”. Musisz więc najpierw skonfigurować strumień 1
FrinkTheBrave
3
@FrinkTheBrave, ale strumień 1 jest standardowym wyjściem (np. Konsolą), jeśli nie jest wyraźnie określony. To wciąż nie tłumaczy tego imho.
MarioDS,
1
@MDeSchaepmeester, jeśli to zrobisz dir 2>&1 > a.txt, najpierw przekierowujesz ( >) strumień 2 (stderr) do strumienia 1 (stdout). Następnie, gdy oba z nich są już połączone, przekierowujesz stdout ( >bez specyfikatora) do pliku. Jeśli chcesz, aby stderr poszedł gdzie indziej, nie możesz najpierw dołączyć do niego ze stdout.
cp.engr
80

Informacje podstawowe z MSKB

Chociaż zaakceptowana odpowiedź na to pytanie jest prawidłowa, tak naprawdę niewiele robi, aby wyjaśnić, dlaczego to działa, a ponieważ składnia nie jest od razu jasna, zrobiłem szybkie google, aby dowiedzieć się, co się właściwie dzieje. W nadziei, że informacje te będą pomocne dla innych, zamieszczam je tutaj.

Zaczerpnięte z MS Support KB 110930 .


Od MSKB110930

Przekierowywanie komunikatów o błędach z wiersza polecenia: STDERR / STDOUT

Podsumowanie

Podczas przekierowywania danych wyjściowych z aplikacji za pomocą symbolu „>” komunikaty o błędach nadal są drukowane na ekranie. Wynika to z faktu, że komunikaty o błędach są często wysyłane do strumienia standardowego błędu zamiast strumienia standardowego.

Dane wyjściowe z aplikacji lub polecenia konsoli (wiersza polecenia) są często wysyłane do dwóch oddzielnych strumieni. Zwykłe wyjście jest wysyłane do Standard Out (STDOUT), a komunikaty o błędach są wysyłane do Standard Error (STDERR). Gdy przekierowujesz wyjście konsoli za pomocą symbolu „>”, przekierowujesz tylko STDOUT. Aby przekierować STDERR, musisz podać „2>” dla symbolu przekierowania. Wybiera drugi strumień wyjściowy, którym jest STDERR.

Przykład

Polecenie dir file.xxx(gdzie file.xxxnie istnieje) wyświetli następujące dane wyjściowe:

Volume in drive F is Candy Cane Volume Serial Number is 34EC-0876

File Not Found

Jeśli przekierujesz dane wyjściowe do NULurządzenia za pomocą dir file.xxx > nul, nadal zobaczysz część komunikatu o błędzie, taką jak ta:

File Not Found

Aby przekierować (tylko) komunikat o błędzie NUL, użyj następującego polecenia:

dir file.xxx 2> nul

Lub możesz przekierować dane wyjściowe do jednego miejsca, a błędy do innego.

dir file.xxx > output.msg 2> output.err

Możesz wydrukować błędy i standardowe dane wyjściowe do jednego pliku, używając polecenia „& 1” w celu przekierowania danych wyjściowych dla STDERR do STDOUT, a następnie wysyłając dane wyjściowe z STDOUT do pliku:

dir file.xxx 1> output.msg 2>&1
StormeHawke
źródło
29

Aby dodać stdout i stderr do ogólnego pliku dziennika skryptu:

dir >> a.txt 2>&1
Henk Wiersema
źródło
9
>>Dopisuje do pliku gdzie >nadpisuje plik.
delliottg
13

Prawidłowo, uchwyt pliku 1 dla procesu to STDOUT, przekierowany przez 1>lub >(1 można zwyczajowo pominąć, interpreter poleceń [cmd.exe] wie, że to obsługuje). Uchwyt pliku 2 to STDERR, przekierowany przez 2>.

Pamiętaj, że jeśli używasz ich do tworzenia plików dziennika, to o ile nie wysyłasz danych wyjściowych do plików dziennika _uniquely_named_ (np. Ze znacznikiem daty i godziny), to jeśli uruchomisz ten sam proces dwukrotnie, przekierowane nadpisze ( zamień) poprzedni plik dziennika.

The >>(Dla obu STDOUT i STDERR) nie doda zastąpić plik. Otrzymujesz skumulowany plik dziennika, pokazujący wyniki ze wszystkich przebiegów procesu - zwykle bardziej użyteczny.

Wesołe szlaki ...

Max Vitesse
źródło
2

Nie ma jednak żadnej gwarancji, że dane wyjściowe SDTOUTi STDERRsą przeplatane linia po linii w odpowiednim czasie, przy użyciuPOSIX składni scalania przekierowań.

Jeśli aplikacja korzysta z buforowanych danych wyjściowych, może się zdarzyć, że tekst jednego strumienia zostanie wstawiony do drugiego na granicy bufora, co może pojawić się na środku wiersza tekstu.

Rejestrator wyjście dedykowane konsoli (Tj "StdOut/StdErr Logger"przez'LoRd MuldeR' ) może być bardziej niezawodny w przypadku takiego zadania.

Zobacz: Projekty OpenSource MuldeR

LigH
źródło
0

W pliku wsadowym (Windows 7 i wyżej) uznałem tę metodę za najbardziej niezawodną

Call :logging >"C:\Temp\NAME_Your_Log_File.txt" 2>&1
:logging
TITLE "Logging Commands"
ECHO "Read this output in your log file"
ECHO ..
Prompt $_
COLOR 0F

Oczywiście użyj dowolnych poleceń, a dane wyjściowe zostaną przekierowane do pliku tekstowego. Korzystanie z tej metody jest niezawodne JEDNAK NIE ma wyjścia na ekranie.

PanamaPHat
źródło
(w zasadzie ta sama odpowiedź udzielona kilka lat temu.) Możesz wymusić wyświetlanie na ekranie za pomocą >con echo This goes to screenPrzydatne również do wprowadzania przez użytkownika >con set /p "var="Input: "Uwaga: te linie pojawią się tylko na ekranie i nie zostaną przekierowane do pliku.
Stephan