wysyłanie danych wyjściowych do / dev / stderr vs.> i 2

11

W skryptach błędy są zwykle wysyłane do deskryptora pliku 2 za pomocą &2, tj .:

echo "error" >&2

Czasami /dev/stderrużywa się zamiast tego:

echo "error" > /dev/stderr 

Patrząc na to /dev/stderr, widzę, że jest to tylko dowiązanie symboliczne /proc/self/fd/2, które z kolei jest dowiązaniem symbolicznym /dev/pts/5(na moim obecnym terminalu).

Wydaje się to trochę skomplikowane. Czy kryje się za tym jakaś logika?

Używa /dev/stderri &2ekwiwalent?

Czy któryś z nich jest preferowany?

Martin Vegter
źródło
3
echo "error" >2tworzy plik z nazwą 2i zawartością error.
Cyrus
Widzę moją edycję ponownie wprowadzoną i 2 zamiast 2. Czy twoje pytanie dotyczy użycia >2lub >&2?
Jeff Schaller

Odpowiedzi:

13

Urządzenie specjalne /dev/stderrjest specyficzne dla systemu, a deskryptor pliku 2(nie urządzenie specjalne /proc/self/fd/2) jest przenośny. Jeśli chcesz pisać nieprzenośny kod, te specjalne urządzenia są dobrym miejscem do rozpoczęcia.

Istnieje kilka systemów z /dev/stderr: Linux oczywiście i OSX . Ale OSX nie ma /procsystemu plików i /dev/stderrjest to link do /dev/fd/2.

Dalsza lektura:

Thomas Dickey
źródło
Jest też przypadek, w którym ktoś chce zrobić np. to 2> bla.logdziałałoby tak długo, jak korzystasz z potoku, 2a nie na stałe /dev/stderr. Zasadniczo 2nie musi to być stderrwynik.
larkey,
6

W bash i innych powłokach sposobem na przekierowanie czegoś do standardowego błędu jest użycie >&2. Bash otwiera się /dev/stderrjako deskryptor pliku 2 . Deskryptory plików są wskazywane przez &Ngdzie Njest numerem deskryptora. Tak, echo error >&2wydrukuje errordo standardowego błędu, do /dev/stderr.

Otworzy się również /dev/stdoutjako deskryptor pliku 1. Oznacza to, że możesz to zrobić echo output >&1. Ponieważ jednak i tak wszystko jest domyślnie drukowane na standardowe wyjście, jest to samo, co samo w echo outputsobie.

Teraz 2>jest inaczej. Przekierowujesz wyjście błędu polecenia gdzieś indziej. 2>fileOznacza więc „przekieruj wszystko wydrukowane do deskryptora pliku 2 (błąd standardowy) do file”.

terdon
źródło
3

Masz rację, >&2jest bardziej bezpośredni i idealnie „idiomatyczny”. Powinny być równoważne, więc nie ma konkretnego powodu, aby z nich korzystać >/dev/stderr. Tyle, że jeśli ktoś czytający nie wie, co one robią, prawdopodobnie łatwiej jest dowiedzieć się jednego z nich :-). Ale ogólnie proponuję użyć >&2.

/ dev / stderr może być przydatny, gdy programy będą zapisywać błędy do określonej nazwy pliku, ale nie obsługują stderr. Oczywiście jest to nieco wymyślone; / dev / stdout jest znacznie bardziej użyteczny. (Niedawno zauważyłem, że mysql_safeskrypt opakowania nie zapisuje błędów w konsoli; niestety chce również zmienić uprawnienia do pliku dziennika błędów, więc użycie / dev / stderr powoduje kilka zbędnych ostrzeżeń).

sourcejedi
źródło