W skryptach błędy są zwykle wysyłane do deskryptora pliku 2 za pomocą &2
, tj .:
echo "error" >&2
Czasami /dev/stderr
uż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/stderr
i &2
ekwiwalent?
Czy któryś z nich jest preferowany?
portability
stderr
Martin Vegter
źródło
źródło
echo "error" >2
tworzy plik z nazwą2
i zawartościąerror
.>2
lub>&2
?Odpowiedzi:
Urządzenie specjalne
/dev/stderr
jest specyficzne dla systemu, a deskryptor pliku2
(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/proc
systemu plików i/dev/stderr
jest to link do/dev/fd/2
.Dalsza lektura:
źródło
2> bla.log
działałoby tak długo, jak korzystasz z potoku,2
a nie na stałe/dev/stderr
. Zasadniczo2
nie musi to byćstderr
wynik.W bash i innych powłokach sposobem na przekierowanie czegoś do standardowego błędu jest użycie
>&2
. Bash otwiera się/dev/stderr
jako deskryptor pliku2
. Deskryptory plików są wskazywane przez&N
gdzieN
jest numerem deskryptora. Tak,echo error >&2
wydrukujeerror
do standardowego błędu, do/dev/stderr
.Otworzy się również
/dev/stdout
jako deskryptor pliku1
. 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 wecho output
sobie.Teraz
2>
jest inaczej. Przekierowujesz wyjście błędu polecenia gdzieś indziej.2>file
Oznacza więc „przekieruj wszystko wydrukowane do deskryptora pliku 2 (błąd standardowy) dofile
”.źródło
Masz rację,
>&2
jest 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_safe
skrypt 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ń).źródło