W powłoce Unix, jeśli chce się połączyć stderr
i stdout
do stdout
strumienia do dalszej manipulacji, mogę dołączyć następujące na koniec mojego polecenia:
2>&1
Więc jeśli chcę użyć head
na wyjściu z g++
, mogę zrobić coś takiego:
g++ lots_of_errors 2>&1 | head
więc widzę tylko kilka pierwszych błędów.
Zawsze mam problem z zapamiętywaniem tego i ciągle muszę to sprawdzać, a to głównie dlatego, że nie do końca rozumiem składnię tej konkretnej sztuczki.
Czy ktoś może to przełamać i wyjaśnić znak po znaku, co 2>&1
to znaczy?
2>&1
niż 2> / dev / null ;-)|&
jest to skrót,2>&1 |
jeśli używasz zsh. Nie mogę porozmawiać o tym, czy dotyczy to innych pocisków typu bourne, czy też jest to funkcja tylko zsh.Odpowiedzi:
Deskryptor pliku 1 jest standardowym wyjściem (
stdout
).Deskryptor pliku 2 jest standardowym błędem (
stderr
).Oto jeden sposób, aby zapamiętać ten konstrukt (choć nie jest to do końca prawda): w pierwszym,
2>1
może wyglądać dobry sposób przekierowaćstderr
dostdout
. Jednak będzie to interpretowane jako „przekierowaniestderr
do pliku o nazwie1
”.&
wskazuje, że poniżej znajduje się deskryptor pliku, a nie nazwa pliku. Więc konstrukt postać:2>&1
.źródło
&2>&1
?&
interpretowany jest jedynie jako „deskryptor pliku” w kontekście przekierowań. Pisaniecommand &2>&
jest analizowane jakocommand &
i2>&1
, tzn. „command
Uruchom w tle, a następnie uruchom polecenie2
i przekieruj jego stdout na stdout”.2>'&1'
przekierowuje standardowe wyjście na
afile.txt
. To jest to samo co robienieAby przekierować stderr, wykonujesz:
>&
to składnia przekierowująca strumień do innego deskryptora pliku - 0 oznacza standardowe wejście, 1 standardowe wyjście, a 2 standardowe.Możesz przekierować stdout na stderr, wykonując:
Lub odwrotnie:
Krótko mówiąc ...
2>
przekierowuje stderr do (nieokreślonego) pliku, dołączając&1
przekierowuje stderr do standardowego wyjścia.źródło
java ... 2&1 >> data.log
, widziałem, jak zrobił to jeden z moich kolegów?cmd 2>&1 >> somefile.log
dołączy plik stdout / stderr do pliku - jest w zasadzie taki sam jak powyżej, z>> file
dołączeniemcmd 2>&1 >>file
nie przekierowuje stderr do pliku, alecmd >> file 2>&1
tak. Zamówienie ma znaczenie. W pierwszym przypadku stderr jest przekierowywany na standardowe wyjście powłoki (być może tty, jeśli polecenie zostanie wprowadzone interaktywnie), a następnie standardowe wyjście jest kierowane do pliku. W drugim przypadku stdout jest kierowany do pliku, a następnie stderr jest kierowany w to samo miejsce.0(or 1,2)>&0(or 1,2)
jak opcja kontroli wyjścia? Czy toecho test >test.log 2>&1
samo coecho test 2>&1 >test.log
?Kilka sztuczek na temat przekierowania
Niektóre szczegóły składni na ten temat mogą mieć ważne zachowania. Istnieje kilka małych próbek o przekierowania,
STDERR
,STDOUT
, i argumenty zamawiającego .1 - Nadpisywanie czy dołączanie?
Symbol
>
oznacza przekierowanie .>
oznacza wysyłanie do jako kompletnego ukończonego pliku , nadpisywanie celu, jeśli istnieje (patrznoclobber
funkcja bash w # 3 później).>>
oznacza, że wysyłanie oprócz dołączałoby do celu, jeśli istnieje.W każdym razie plik zostałby utworzony, gdyby nie istniał.
2 - Wiersz poleceń powłoki zależy od kolejności !!
Do przetestowania tego potrzebujemy prostego polecenia, które wyśle coś na oba wyjścia :
(Oczywiście, że nie masz katalogu o nazwie
/tnt
;). Cóż, mamy to !!Zobaczmy więc:
Ostatni wiersz poleceń zrzuca
STDERR
konsolę i wydaje się, że nie jest to oczekiwane zachowanie ... Ale ...Jeśli chcesz wykonać filtrowanie wpisów dotyczące jednego wyjścia, drugiego lub obu:
Zauważ, że ostatni wiersz polecenia w tym akapicie jest dokładnie taki sam jak w poprzednim akapicie, w którym napisałem, wydaje się, że nie jest to oczekiwane zachowanie (więc może to być nawet oczekiwane zachowanie).
Cóż, jest kilka sztuczek na temat przekierowań, aby wykonać inną operację na obu wyjściach :
Nota:
&9
deskryptor wystąpiłby spontanicznie z powodu) 9>&2
.Dodatek: nota! Dzięki nowej wersjigrzmotnąć(
>4.0
) dostępna jest nowa funkcja i bardziej seksowna składnia do robienia takich rzeczy:I wreszcie dla takiego kaskadowego formatowania wyjściowego:
Dodatek: nota! Ta sama nowa składnia na dwa sposoby:
Gdzie
STDOUT
przechodzą przez określony filtr,STDERR
do drugiego i na końcu oba połączone wyjścia przechodzą przez trzeci filtr poleceń.3 - Słowo o
noclobber
opcji i>|
składniChodzi o nadpisywanie :
Choć
set -o noclobber
Instruct bash aby nie nadpisać istniejącego pliku,>|
składnia pozwala przechodzić przez to ograniczenie:Plik jest zastępowany za każdym razem, a teraz:
Przekaż za pomocą
>|
:Wyłączenie tej opcji i / lub sprawdzenie, czy jest już ustawione.
4 - Ostatnia sztuczka i więcej ...
Przekierowując oba dane wyjściowe z danego polecenia, widzimy, że poprawna składnia może być:
w tym szczególnym przypadku istnieje składnia skrótu:
&>
... lub>&
Uwaga: jeśli
2>&1
istnieje,1>&2
to również poprawna składnia:4b- Teraz pozwolę ci pomyśleć o:
4c- Jeśli chcesz uzyskać więcej informacji
Możesz przeczytać dokładną instrukcję, naciskając:
w grzmotnąć konsola ;-)
źródło
Znalazłem ten świetny post na temat przekierowań: Wszystko o przekierowaniach
Przekieruj zarówno standardowe wyjście, jak i standardowy błąd do pliku
Ten jednowierszowy używa
&>
operatora do przekierowywania obu strumieni wyjściowych - stdout i stderr - z polecenia do pliku. Jest to skrót Basha do szybkiego przekierowywania obu strumieni do tego samego miejsca docelowego.Oto jak wygląda tabela deskryptorów plików po przekierowaniu obu strumieni przez Bash:
Jak widać, zarówno stdout, jak i stderr wskazują teraz
file
. Więc wszystko, co napisano na stdout i stderr, zostaje napisane nafile
.Istnieje kilka sposobów przekierowania obu strumieni do tego samego miejsca docelowego. Możesz przekierowywać każdy strumień jeden po drugim:
Jest to o wiele bardziej powszechny sposób przekierowywania obu strumieni do pliku. Najpierw stdout jest przekierowywany do pliku, a następnie stderr jest duplikowany, aby był taki sam jak stdout. Tak więc oba strumienie kończą się na
file
.Gdy Bash widzi kilka przekierowań, przetwarza je od lewej do prawej. Przejdźmy przez kolejne kroki i zobaczmy, jak to się dzieje. Przed uruchomieniem jakichkolwiek poleceń tabela deskryptorów plików Bash wygląda następująco:
Teraz Bash przetwarza pierwszy plik przekierowania>. Widzieliśmy to już wcześniej i sprawia, że stdout wskazuje na plik:
Następnie Bash widzi drugie przekierowanie 2> i 1. Nigdy wcześniej nie widzieliśmy tego przekierowania. Ten powiela deskryptor pliku 2 jako kopię deskryptora pliku 1 i otrzymujemy:
Oba strumienie zostały przekierowane do pliku.
Uważaj jednak tutaj! Pisanie
to nie to samo co pisanie:
Kolejność przekierowań ma znaczenie w Bash! To polecenie przekierowuje tylko standardowe wyjście do pliku. Stderr nadal będzie drukował na terminalu. Aby zrozumieć, dlaczego tak się dzieje, przejdźmy ponownie przez kolejne kroki. Tak więc przed uruchomieniem polecenia tabela deskryptorów plików wygląda następująco:
Teraz Bash przetwarza przekierowania od lewej do prawej. Najpierw widzi 2> i 1, więc powiela stderr do stdout. Tabela deskryptorów plików staje się:
Teraz Bash widzi drugie przekierowanie
>file
i przekierowuje standardowe wyjście do pliku:Widzisz co się tutaj dzieje? Stdout wskazuje teraz na plik, ale stderr nadal wskazuje na terminal! Wszystko, co zostanie napisane do stderr, nadal zostanie wydrukowane na ekranie! Bądź więc bardzo, bardzo ostrożny z kolejnością przekierowań!
Zauważ też, że w Bash pisze
jest dokładnie taki sam jak:
źródło
>&
/dev/tty0
?Liczby odnoszą się do deskryptorów plików (fd).
stdin
stdout
stderr
2>&1
przekierowuje fd 2 na 1.Działa to dla dowolnej liczby deskryptorów plików, jeśli program ich używa.
Możesz sprawdzić,
/usr/include/unistd.h
jeśli je zapomnisz:Powiedziałem, że napisałem narzędzia C, które używają niestandardowych deskryptorów plików do niestandardowego rejestrowania, więc nie widzisz go, dopóki nie przekierujesz go do pliku lub czegoś innego.
źródło
Ta konstrukcja wysyła standardowy strumień błędów (
stderr
) do bieżącej lokalizacji standardowego wyjścia (stdout
) - ten problem walutowy wydaje się być zaniedbany przez inne odpowiedzi.Za pomocą tej metody można przekierować dowolny uchwyt wyjściowy na inny, ale najczęściej jest on używany do kierowania
stdout
istderr
przesyłania strumieni do jednego strumienia w celu przetworzenia.Oto niektóre przykłady:
Zauważ, że ten ostatni będzie nie kierować
stderr
dooutfile2
- przekierowuje je do tego, costdout
było, gdy argument napotkano (outfile1
), a następnie przekierowujestdout
dooutfile2
.Pozwala to na dość wyrafinowane oszustwo.
źródło
some_program 2>&1 > /dev/null
nie działa tak:some_program > /dev/null 2>&1
.2>&1
jest konstrukcją powłoki POSIX. Oto podział, token po tokenie:2
: Deskryptor pliku wyjściowego „ Błąd standardowy ”.>&
: Zduplikuj operator deskryptora pliku wyjściowego (wariant operatora przekierowania danych wyjściowych>
). Biorąc pod uwagę[x]>&[y]
, deskryptor pliku oznaczony jakox
jest tworzony jako kopia deskryptora pliku wyjściowegoy
.1
Deskryptor pliku wyjściowego „ Standardowe wyjście ”.Wyrażenie
2>&1
kopiuje deskryptor pliku1
do lokalizacji2
, więc każde wyjście zapisane w2
(„błąd standardowy”) w środowisku wykonawczym trafia do tego samego pliku, który został pierwotnie opisany przez1
(„wyjście standardowe”).Dalsze wyjaśnienia:
Deskryptor pliku : „Unikalna na liczbę procesów, nieujemna liczba całkowita używana do identyfikowania otwartego pliku w celu uzyskania dostępu do pliku”.
Standardowe wyjście / błąd : Zapoznaj się z następującą uwagą w sekcji Przekierowanie dokumentacji powłoki:
źródło
2 jest standardowym błędem konsoli.
1 to standardowe wyjście konsoli.
Jest to standardowy Uniks, a system Windows również postępuje zgodnie z POSIX.
Np. Kiedy biegniesz
błąd standardowy jest przekierowywany na standardowe wyjście, dzięki czemu można zobaczyć oba wyjścia razem:
Po wykonaniu możesz wyświetlić wszystkie dane wyjściowe, w tym błędy, w pliku debug.log.
Następnie standardowe wyjście przechodzi do out.log, a standardowy błąd do err.log.
Sugeruję, abyś spróbował je zrozumieć.
źródło
perl test.pl > debug.log 2>&1
Aby odpowiedzieć na twoje pytanie: Pobiera każdy wynik błędu (zwykle wysyłany do stderr) i zapisuje go na standardowe wyjście (stdout).
Jest to pomocne, na przykład „więcej”, gdy potrzebujesz stronicowania dla wszystkich danych wyjściowych. Niektóre programy, takie jak drukowanie informacji o użyciu do stderr.
Aby pomóc ci zapamiętać
„2> i 1” po prostu wskazuje wszystko wysłane do stderr, zamiast do stdout.
Polecam również przeczytanie tego postu na temat przekierowywania błędów, gdy ten temat jest szczegółowo opisany.
źródło
Z punktu widzenia programisty oznacza to dokładnie to:
Zobacz stronę manuala .
Zrozumienie, że
2>&1
jest to kopia, wyjaśnia również, dlaczego ...... to nie to samo co ...
Pierwszy wyśle oba strumienie do
file
, a drugi wyśle błędystdout
i zwykłe wyjście dofile
.źródło
Uważam to za bardzo pomocne, jeśli jesteś początkującym, przeczytaj to
Aktualizacja:
W systemie Linux lub Unix istnieją dwa miejsca, w których programy wysyłają dane wyjściowe: Standardowe wyjście (stdout) i Standardowy błąd (stderr) . Możesz przekierować te dane wyjściowe do dowolnego pliku.
Tak, jak to zrobisz
ls -a > output.txt
Nic nie zostanie wydrukowane w konsoli, wszystkie dane wyjściowe (standardowe wyjście) zostaną przekierowane do pliku wyjściowego.
A jeśli spróbujesz wydrukować zawartość dowolnego pliku, który nie wychodzi, oznacza to, że na wyjściu pojawi się błąd, tak jak podczas drukowania test.txt, którego nie ma w bieżącym katalogu
cat test.txt > error.txt
Wyjście będzie
Ale plik error.txt będzie pusty, ponieważ przekierowujemy stdout do pliku innego niż stderr.
więc potrzebujemy deskryptora pliku (deskryptor pliku to nic innego jak dodatnia liczba całkowita reprezentująca otwarty plik. Można powiedzieć, że deskryptor jest unikalnym identyfikatorem pliku), aby powiedzieć powłoce, jaki typ danych wyjściowych wysyłamy do pliku. W systemie Unix / Linux 1 jest dla standardowego wyjścia, a 2 dla standardowego .
więc teraz, jeśli to zrobisz,
ls -a 1> output.txt
oznacza to, że wysyłasz Standardowe wyjście (stdout) do output.txt.a jeśli to zrobisz,
cat test.txt 2> error.txt
oznacza to, że wysyłasz błąd standardowy (stderr) na error.txt.&1
służy do odwoływania się do wartości deskryptora pliku 1 (standardowe wyjście).Teraz do rzeczy
2>&1
oznacza „Przekieruj stderr w to samo miejsce, w którym przekierowujemy stdout”Teraz możesz to zrobić
cat maybefile.txt > output.txt 2>&1
zarówno Standardowe wyjście (stdout), jak i Standardowy błąd (stderr) zostaną przekierowane do output.txt.
Dzięki Ondrej K. za wskazanie
źródło
Ludzie, zawsze pamiętam wskazówkę paxdiablo na temat aktualnej lokalizacji docelowej przekierowania ... To jest ważne.
Mój osobisty mnemonik dla
2>&1
operatora jest następujący:&
znaczeniu'and'
lub'add'
(postać to ampery - i prawda?)2
(stderr) do miejsca1
(stdout) już / obecnie jest i dodaj oba strumienie” .Ta sama mnemoniczna działa również w przypadku innych często używanych przekierowań
1>&2
:&
znaczeniuand
lubadd
... (masz pomysł na ampersand, tak?)1
(stdout) tam, gdzie2
(stderr) już / obecnie jest i dodaj oba strumienie” .I zawsze pamiętaj: musisz czytać łańcuchy przekierowań „od końca”, od prawej do lewej ( nie od lewej do prawej).
źródło
Ref:
Wpisz,
/^REDIRECT
aby zlokalizowaćredirection
sekcję i dowiedz się więcej ...Dostępna jest wersja online: 3.6 Przekierowania
PS:
Wiele czasu
man
było potężnym narzędziem do nauki Linuksa.źródło
Pod warunkiem, że
/foo
nie istnieje w systemie i/tmp
…wydrukuje zawartość
/tmp
i wydrukuje komunikat błędu dla/foo
wyśle zawartość od
/tmp
celu/dev/null
i wydrukować komunikat o błędzie dla/foo
zrobi dokładnie to samo (zwróć uwagę na 1 )
wydrukuje zawartość
/tmp
i wyśle komunikat o błędzie na adres/dev/null
wyśle zarówno wpis, jak i komunikat błędu do
/dev/null
jest skrótem
źródło
To jest jak przekazanie błędu do standardowego wyjścia lub terminala.
Oznacza to, że
cmd
nie jest poleceniem:Błąd jest wysyłany do pliku w następujący sposób:
Standardowy błąd jest wysyłany do terminala.
źródło
0 dla wejścia, 1 dla standardu i 2 dla standardu.
Jedna wskazówka :
somecmd >1.txt 2>&1
jest poprawna, podczas gdysomecmd 2>&1 >1.txt
całkowicie błędna bez efektu!źródło
unix_commands 2>&1
Służy do drukowania błędów na terminalu.
Poniżej przedstawiono proces
&2
„bufor”, z którego pochodzi standardowy strumień błędów2
odwołuje się .&1
„bufor”, z którego1
odwołuje się standardowy strumień wyjściowy .Tak więc weź
unix_commands
standardowy strumień błędów2
i przekieruj>
strumień (błędów) na standardowy adres pamięci wyjściowej&1
, aby były one przesyłane strumieniowo do terminala i drukowane.źródło