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ć”?
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ć”?
Odpowiedzi:
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 grep
bezpośrednio plik, ale to nie wyjaśnia, jak to działa, prawda?
To łączy standardowe wyjście cat
polecenia ze standardowym wejściem grep
polecenia. cat
wysyła zawartość pliku na standardowe wyjście i grep
odczytuje 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ć pager
zamknięcie rury wejściowej przez proces przed cat
zakoń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ć.
pr -e4 -n ten-thousand-lines.c | sed 10q
kończy się zepsutą rurą. To, czy pr
przeszkadza 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).
|
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
head
Komenda 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 cat
pozostawaniu 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.
Ten błąd pojawia się dość często. /programming/490366/ad-hoc-deployment-issue-putpkt-write-failed-broken-pipe to „... wewnętrzny błąd w zdolności Xcode do rozmowy z telefonem. oznacza, że zrobiłeś coś złego, to błąd w systemie programistycznym ”
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.txt
zastępuje wszystkie wystąpienia ciągu foo
łańcuchem, bar
a następnie wyszukuje w wynikach wiersze zawierające bar
nastę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 awk
lub perl
do 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 SIGPIPE
sygnał. A jeśli zablokuje ten sygnał, write
nadal zawiedzie ze specjalnym rodzajem błędu wskazującego, że rura „pękła”.
Domyślna obsługa SIGPIPE
zabija proces, który je odbiera. A jeśli nie jest to „głowa” rurociągu, cała SIGPIPE
rzecz 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.
„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
cat
Proces posiada końcówkę do pisania rury, a less
proces 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.
cat
oczywiście po jego zakończeniu), czytelnik po prostu zobaczy normalny koniec pliku.