Co to jest „rura” i jak można ją „złamać”?


12

wprowadź opis zdjęcia tutaj

Wystąpił błąd „złamanej rury” z Xcode raz za dużo. Teraz jestem ciekawy, co to dokładnie jest rura.

Jaka jest koncepcja „fajki” i jak można ją „złamać”?


3
Rura to długa rura, która zawiera wiele danych. Jeśli odbierający koniec potoku przestaje wyciągać dane, zaczyna się tworzenie kopii zapasowej i rura pęka. Komputer informuje koniec, który wkłada dane do potoku, że tak się stało.
Wszechobecny

Odpowiedzi:


7

Rura jest po prostu mechanizmem komunikacji międzyprocesowej (IPC) używanym do łączenia standardowego wyjścia jednego procesu ze standardowym wejściem innego.

Przykładem jest szukanie w pliku słowa „pax”:

cat filename | grep pax

i tak, wiem, że możesz grepbezpośrednio plik, ale to nie wyjaśnia, jak to działa, prawda?

To łączy standardowe wyjście catpolecenia ze standardowym wejściem greppolecenia. catwysyła zawartość pliku na standardowe wyjście i grepodczytuje plik (w tym przypadku) ze standardowego wejścia. Łącząc procesy w ten sposób, możesz tworzyć własne narzędzia składające się z dowolnej liczby segmentów rur. Rzeczy jak:

show_users | grep pax | awk -F: '{print $4}' | tr '[a-z]' '[A-Z]' | cut -c1-20

Uszkodzony przewód jest jednym gdzie (zazwyczaj) odbiornik danych zamknął połączenie, gdy nadawca wciąż próbuje wysłać rzeczy dzięki.

Na przykład, jeśli wysyłasz duży plik za pomocą programu pager (aby wyświetlić go pojedynczo):

cat myfile | pager

a następnie wykonaj a CTRL-BREAK, może to spowodować pagerzamknięcie rury wejściowej przez proces przed catzakończeniem jego używania. To jedna z możliwości zdobycia tej zepsutej rury.


Z pobieżnej wyszukiwarki Google ten konkretny problem wydaje się być związany z wdrożeniami ad hoc, a podane rozwiązania zwykle obejmują wyjście z większości oprogramowania i ponowne uruchomienie większości urządzeń.

Jest to prawdopodobnie wystarczająco poważne, aby zgłosić problem Apple. Im więcej programistów narzeka na to, tym bardziej prawdopodobne jest, że coś zostanie zrobione, aby to naprawić.


Czym jest „zepsuta” rura?
Moshe,

pr -e4 -n ten-thousand-lines.c | sed 10qkończy się zepsutą rurą. To, czy prprzeszkadza ci powiedzieć, że dostał sygnał SIGPIPE, to inna sprawa; może również po prostu wyjść w wyniku sygnału (generując niezerowy status wyjścia).
Jonathan Leffler,

Rury mają nie koniecznie podłączyć „standard” wejście i wyjście. Możliwe jest programowo przepuszczenie dowolnego wejścia / wyjścia przez potok, chociaż z linii poleceń masz poprawność.
CarlF

2

|Postać jest często nazywany jest rura. W różnych powłokach UNIX (które znam) można go wykorzystać do potokowania danych wyjściowych jednego polecenia do danych wejściowych drugiego.

cat myfile.txt | head

headKomenda pokazuje tylko pierwsze kilka linijek swojego wejścia. W tym momencie zamyka wejście. Stanowi to problem dla polecenia, które generowało dane wejściowe. Gdzie to pisze? Ilekroć mamy taką sytuację lub sytuację, w której proces pisania kończy się, zanim czytelnik się skończy, nazywa się to „przerwaną rurą”.

Aby zapobiec catpozostawaniu polecenia na zawsze, standard UNIX definiuje specjalny sygnał ( SIGPIPE , sygnał 13 ), do którego wysyła cat. Domyślną akcją dla tego sygnału jest zabicie procesu, co catładnie kończy koniec.

Wygląda na to, że aplikacja, której używasz, zainstalowała moduł obsługi sygnałów dla wszystkich sygnałów, w tym SIGPIPE, który tworzy małe wyskakujące okienko, które widzisz.



1

Rura jest mechanizmem IPC w systemach Unix. Potok ma dwa końce, koniec odczytu i koniec zapisu. Dane zapisywane na końcu zapisu można odczytać z końca odczytu i wychodzą w kolejności, w jakiej zostały zapisane.

W świecie wiersza poleceń Uniksa potoki są bardzo popularnym sposobem łączenia programów w celu wykonania zadania. Na przykład sed 's/foo/bar/g' fred.txt | grep -e 'bar.*baz'czyta w pliku, fred.txtzastępuje wszystkie wystąpienia ciągu foołańcuchem, bara następnie wyszukuje w wynikach wiersze zawierające barnastępującą liczbę znaków, a następnie baz.

To oczywiście nie wydaje się zbyt przydatne. Ale jestem pewien, że jeśli pomyślisz o tym, możesz zobaczyć, jak możesz wykorzystać to do różnego rodzaju interesujących zastosowań, zwłaszcza gdy masz programy takie jak awklub perldo dyspozycji.

System rur jest częścią Uniksa od samego początku. A jeśli proces w potoku zakończy się, zwykle chcesz, aby wszystkie programy w potoku zakończyły działanie. Oznacza to, że domyślnie proces, który zapisuje do potoku, gdy proces po zakończeniu odczytu zniknął, otrzyma SIGPIPEsygnał. A jeśli zablokuje ten sygnał, writenadal zawiedzie ze specjalnym rodzajem błędu wskazującego, że rura „pękła”.

Domyślna obsługa SIGPIPEzabija proces, który je odbiera. A jeśli nie jest to „głowa” rurociągu, cała SIGPIPErzecz rozprzestrzenia się z powrotem w górę łańcucha.

Xcode narzeka na to, że uruchomił jakiś podprogram, aby zrobić coś z prowadzącą do niego potokiem, i ten podprogram nieoczekiwanie zmarł, pozostawiając potok zepsuty.


0

„Złamana” rura to taka, w której jeden koniec został zakończony, close()a drugi jest odczytywany lub zapisywany. Na przykład w następującym poleceniu powłoki:

cat foo | less

catProces posiada końcówkę do pisania rury, a lessproces odczyt jednego. Jeśli proces czytnika zamyka potok, potok jest zepsuty (a zatem bezużyteczny); proces zapisu otrzyma błąd „zepsutej rury” z systemu operacyjnego.


1
W rzeczywistości jest „zepsuty” tylko wtedy, gdy czytelnik go zamknie. Jeśli piszący go zamknie ( catoczywiście po jego zakończeniu), czytelnik po prostu zobaczy normalny koniec pliku.
Random832

Ups, masz całkowitą rację ... Zaktualizuję moją odpowiedź.
Michael Trausch
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.