2012-04-05 16 views
17

To nastrojową polecenia do generowania 10 znaków hasła na chybił trafił:Dlaczego ta rura jest zakończona?

cat /dev/urandom | base64 | head -c 10 

Moje pytanie brzmi: cat /dev/urandom | base64 jest nieskończony strumień wyjściowy, który nie zatrzyma się samoczynnie. Ale dlaczego dołączenie head -c 10 powoduje zakończenie całej rury? Zakładam, że cat, base64 i head są 3 oddzielnymi procesami, w jaki sposób można je zakończyć?

Odpowiedz

11

Po base64 wyprowadza 10 bajtów, head dostaje wystarczającą liczbę wejść i wyjść. Kiedy pierwsza z nich spróbuje wyprowadzić więcej bajtów, otrzyma ona SIGPIPE signal, a tym samym również wyjdzie. Z tego samego powodu, cat zostanie opuszczone po kolei.

23

head zamyka plik wejściowy po odczytaniu wymaganej ilości. gdy rura jest zamknięta z jednej strony, druga strona otrzymuje błędy zapisu; to powoduje zamknięcie base64, co z kolei powoduje zamknięcie cat.

+7

Warto wspomnieć, że jedynym powodem, dla którego 'head' w ogóle dostaje jakiekolwiek dane wejściowe, jest to, że' base64' zapisuje dane wyjściowe po tym, jak otrzymuje pewną ilość danych wejściowych, tj. Gdy bufor jest pełny. Jeśli miałby czytać do EOF, byłby to czytanie na zawsze, a "głowa" nigdy by się nie rozbiła. Tak podobny rurociąg, jak 'cat/dev/urandom | suma head -c 10' zachowałoby się inaczej, ponieważ 'sum' czeka na EOF. –

+3

s/dostaje błędy zapisu/odbiera SIGPIPE/ –

+1

Komentarz Roba * jest * bardzo * istotny. Jeśli proces dziedziczy program obsługi SIGPIPE lub ignoruje SIGPIPE (np. Jeśli jest uruchamiany pod starszym modułem podprocesów interpretera starszych pythonów) i nie sprawdza błędów zapisu, nie zostanie zakończony. Występuje * ogromna * różnica między błędem zapisu i odbieraniem SIGPIPE, a programy, które ignorują oba problemy, są podatne na działanie w nieskończoność. –

4

rurowe działa poprzez połączenie wyjścia jednego sposobu A do wejścia B. Połączenie może zostać uszkodzony, jeśli

  • zamyka wyjście. B otrzyma EOF.
  • B zamyka dane wejściowe. A otrzyma błąd, że dane wyjściowe nie będą już dostępne podczas próby zapisania następnego bajtu.

Ponieważ te dwa przypadki są tak częste, obsługa została przeniesiona do biblioteki standardowej C.

+0

Dzięki, ale co znaczy "obsługa przeniesiona do biblioteki standardowej C"? czy A i B kończą się powłoką, zamiast wykrywają zamknięcie wejścia/wyjścia i same się zatrzymują? – Dagang

+0

Gdy B zamyka bok rury, A odbierze sygnał. Kod w procedurach I/O standardowej biblioteki c.lib ('fprintf()', 'open()', 'read()', ...) obsługuje sygnał i wywołanie funkcji zwróci powrót errno EPIPE = "Zerwana rura". –

+1

@AaronDigulla, nie zgadzam się. Nie jestem świadomy żadnej biblioteki C, która instaluje program obsługi SIGPIPE, ani nie sugerują tego moje eksperymenty. W rzeczywistości dostarczono SIGPIPE, co powoduje, że program, który nie zainstalował programu obsługi (tj. 99% wszystkich programów), kończy pracę. –

Powiązane problemy