wiem co
program > /dev/null 2>&1
robi. Przekierowuje wyjście do /dev/null
i 2>&1
oznacza przekierowanie wyjścia błędu w tym samym miejscu, w którym wysyłane jest wyjście.
Mój problem polega na tym, że zawsze muszę go wyszukiwać w Google, ponieważ nigdy tego nie pamiętam.
Więc staram &2>1
, 1>2&
, 1>&2
... Staram każdą kombinację aż google ...
Jak łatwo jest to zapamiętać?
program 1> /dev/null 2>/dev/null
. Czasami jednak trzeba wymieszaćstdout
istderr
razem, aby zobaczyć, co się naprawdę dzieje - na przykład przekierowanie wyjścia do złożonego procesu kompilacji do pliku. W takim razieOdpowiedzi:
Wyjście jest lepsze niż błąd, więc jest pierwsze (1 vs 2).
>
jest skrótem od „idzie do”. Po lewej stronie jest to, co chcę wysłać, a po prawej to miejsce, w którym chcę to wysłać. Ponieważ „gdzie” jest (prawie) zawsze plikiem, coś w rodzajuprzekieruje do pliku o nazwie 1. Zatem znak ampersand
(&)
modyfikuje plik do deskryptora pliku.Niestety nie spotkałem się ani nie opracowałem własnego mnemonika, ale kiedy uczyłem się * nix, znalazłem ten logiczny sposób, aby dobrze działać. Po kilku przejściach staje się drugą naturą.
źródło
stdout
jest deskryptorem pliku 1,stderr
ma 2. Zatem „błąd” występuje przed „wyjściem”.stdout
i do któregostderr
odnosi się.Jedną sztuczką jest, aby pamiętać, że 1 = standardowe wyjście, 2 = standardowy błąd. Więc:
2>&1
= standardowy strumień błędów przechodzi do standardowego strumienia wyjściowego.1>&2
= vice versa.Jeśli kiedykolwiek programowałeś w języku podobnym do C, łatwo jest zapamiętać ampersand (
&
). Wybieram myślenie o nim jako o „adresie” istniejącego deskryptora pliku, abyś nie zmienił samego pliku ani nie utworzył nowego.źródło
Uznanie
&
za węzeł może pomóc: pomyśl o tym, co chcesz zrobić, biorąc wynik 2, więc2>
i wiążąc go z 1, więc2>&1
źródło
W rzeczywistości zależy to od używanej powłoki. Bash jest zwykle bardzo wybaczający i możesz po prostu zrobić:
źródło
Rozważmy te trzy opcje:
Pierwszy wysyła stderr do nazw plików „1”: w końcu bash oczekuje przekierowania do pliku.
Drugi również przekierowuje do tego samego pliku, ale działa
program
w tle: to właśnie&
powinien oznaczać końcowy .To pozostawia trzecią możliwość jako jedyną, która ma sens we wszechświecie bash do przekierowywania do uchwytu pliku.
Jak zapamiętać, który z nich jest 0, 1, 2? Pomyśl o uruchomieniu komputera z konsoli. Najpierw musisz coś wpisać (0 = stdin). Następnie zobaczysz wynik (1 = standardowe wyjście). Wreszcie, tylko jeśli coś pójdzie nie tak, zobaczysz stderr (2).
źródło
Narysuj to na tapecie.
Poważnie, o tym i innych podstawowych rzeczach zapomniałem, dlatego dodałem szybkie menu wskazówek do opracowanej przeze mnie aplikacji, z której korzystam codziennie. Możesz spróbować i użyć czegoś takiego jak gnote, aby zachować notatkę.
źródło
Jeśli chodzi o powłokę bash, najlepszym sposobem na zapamiętanie jest zrozumienie tego, co się dzieje.
Jeśli wszystko, co chcesz zrobić, to pamiętać, jak poprawnie wykonać polecenie, możesz spróbować
To miłe i oczywiste, co się dzieje i łatwe do zapamiętania. to znaczy
1
STDOUT zamierza/results
2
STDERR również idzie bezpośrednio do/results
problem polega na tym, że to nie działa tak, jak można się spodziewać. rozważ następujące:
plik:
/tmp/poem.txt
i uruchom polecenie
następnie
Co tu się stało?
Rozumiem, że bash konfiguruje przekierowanie kierujące STDERR bezpośrednio do pliku
/tmp/results
i ze względu na naturę,>
która robi 2 rzeczy>>
robi.Tak więc w tym przypadku STDERR, wstawia bezpośrednio na początku
/tmp/results
przesłaniania wyjścia STDOUT.Uwaga: jeśli
>>
używałeś dołączania, prawdopodobnie mógłbyś uniknąć tej składni.Jednak, aby rozwiązać problem, którego potrzebujesz - nie przekierowywać STDERR - bezpośrednio do pliku, ale raczej połączyć dane wyjściowe STDERR ze strumieniem STDOUT, aby uniknąć kolizji.
Korzystanie z operatora
2>&1
operatora osiąga to&
Umożliwia bash do odróżnienia od pliku o nazwie1
i1
deskryptora pliku.Dla mnie
2>&1
samo stwierdzenie dokładnie wyjaśnia, co się dzieje - STDERR jest przekierowywany do samego STDOUT - i kończy się na tym,/tmp/results
ponieważ właśnie tam jest wskazany STDOUT (prawie jako efekt uboczny).W przeciwieństwie do tego, co twierdzą wiele przewodników,
2>&1
wysyła STDERR tam, gdzie jest zawsze wskazywany STDOUT. Gdyby tak było - nadal występowałby problem z nadpisywaniem.Aby uzyskać więcej informacji, zobacz - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection
źródło