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?


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 .


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

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


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 ...


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


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.


(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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.