Ich habe den Fehler "broken pipe" einmal zu oft von Xcode erhalten. Jetzt bin ich gespannt, was eine Pfeife genau ist.
Was ist das Konzept einer "Pipe" und wie kann sie "gebrochen" werden?
Ich habe den Fehler "broken pipe" einmal zu oft von Xcode erhalten. Jetzt bin ich gespannt, was eine Pfeife genau ist.
Was ist das Konzept einer "Pipe" und wie kann sie "gebrochen" werden?
Antworten:
Eine Pipe ist einfach ein IPC-Mechanismus (Interprozesskommunikation), mit dem die Standardausgabe eines Prozesses mit der Standardeingabe eines anderen Prozesses verbunden wird.
Ein Beispiel ist, wenn Sie eine Datei nach dem Wort "pax" durchsuchen möchten:
cat filename | grep pax
und ja, ich weiß, Sie können grep
die Datei direkt, aber das erklärt nicht, wie es funktioniert, oder?
Dies verbindet die Standardausgabe des cat
Befehls mit der Standardeingabe des grep
Befehls. cat
Sendet den Inhalt der Datei an die Standardausgabe und grep
liest die Datei (in diesem Fall) von der Standardeingabe. Indem Sie Prozesse auf diese Weise miteinander verbinden, können Sie Ihre eigenen Werkzeuge erstellen, die aus einer beliebigen Anzahl von Rohrsegmenten bestehen. Dinge wie:
show_users | grep pax | awk -F: '{print $4}' | tr '[a-z]' '[A-Z]' | cut -c1-20
Eine defekte Pipe ist eine Pipe, bei der (normalerweise) der Empfänger der Daten die Verbindung geschlossen hat, während der Absender noch versucht, Daten zu senden.
Wenn Sie beispielsweise eine große Datei über ein Pager-Programm senden (um sie seitenweise anzuzeigen):
cat myfile | pager
Wenn Sie dann a ausführen CTRL-BREAK, kann dies dazu führen, dass der pager
Prozess seine Eingangsleitung herunterfährt, bevor er nicht mehr cat
verwendet wird. Das ist eine Möglichkeit, dieses kaputte Rohr zu bekommen.
Aus einer flüchtigen Google-Suche geht hervor , dass dieses bestimmte Problem mit Ad-hoc-Bereitstellungen zusammenhängt. Zu den angegebenen Lösungen gehört normalerweise das Beenden eines Großteils Ihrer Software und das Neustarten der meisten Geräte.
Dies ist wahrscheinlich schwerwiegend genug, um das Problem Apple zu melden. Je mehr Entwickler sich darüber beschweren, desto wahrscheinlicher wird etwas unternommen, um das Problem zu beheben.
pr -e4 -n ten-thousand-lines.c | sed 10q
endet mit einem Rohrbruch. Ob pr
bothers Ihnen zu sagen , dass es bekam das SIGPIPE Signal eine andere Sache; es kann durchaus einfach als Ergebnis des Signals verlassen werden (was einen Nicht-Null-Austrittsstatus erzeugt).
Der |
Charakter wird oft Pipe genannt. In den verschiedenen UNIX-Shells (von denen ich weiß) kann es verwendet werden, um die Ausgabe eines Befehls an die Eingabe eines anderen zu leiten.
cat myfile.txt | head
Der head
Befehl zeigt nur die ersten Zeilen seiner Eingabe an. Zu diesem Zeitpunkt wird die Eingabe geschlossen. Dies ist ein Problem für den Befehl, der die Eingabe generiert hat. Wohin schreibt es? Immer wenn wir diese Situation haben oder wenn der Schreibvorgang endet, bevor der Leser fertig ist, spricht man von einer "kaputten Pipe".
Um zu verhindern, dass der cat
Befehl für immer andauert , definiert der UNIX-Standard ein spezielles Signal ( SIGPIPE , Signal 13 ), an das er gesendet wird cat
. Die Standardaktion für dieses Signal ist, den Prozess cat
abzubrechen , was das Ende angenehm macht.
Anscheinend hat die von Ihnen verwendete Anwendung einen Signal-Handler für alle Signale installiert, einschließlich SIGPIPE, der die kleine Popup-Meldung erstellt, die Sie sehen.
Dieser Fehler scheint ziemlich oft aufzutreten. /programming/490366/ad-hoc-deployment-issue-putpkt-write-failed-broken-pipe Es ist "... ein interner Fehler in der Fähigkeit von Xcode, mit Ihrem Telefon zu sprechen. Es funktioniert nicht Ich meine, Sie haben etwas falsch gemacht, es ist ein Fehler im Entwicklungssystem. "
Eine Pipe ist ein IPC-Mechanismus auf Unix-Systemen. Eine Pipe hat zwei Enden, ein Leseende und ein Schreibende. In das Schreibende geschriebene Daten können vom Leseende gelesen werden und werden in der Reihenfolge ausgegeben, in der sie geschrieben wurden.
In der Unix-Kommandozeilenwelt sind Pipes eine sehr verbreitete Methode, Programme zusammenzufügen, um einen Job zu erledigen. Zum Beispiel sed 's/foo/bar/g' fred.txt | grep -e 'bar.*baz'
wird in der Datei gelesen, fred.txt
dass alle Instanzen der Zeichenfolge foo
durch die Zeichenfolge ersetzt werden. bar
Dann wird das Ergebnis nach Zeilen durchsucht, die bar
gefolgt von einer bestimmten Anzahl von Zeichen enthalten baz
.
Das scheint natürlich nicht besonders nützlich zu sein. Aber ich bin sicher, wenn Sie darüber nachdenken, können Sie sehen, wie Sie das für alle möglichen interessanten Zwecke einsetzen können, besonders wenn Sie Programme wie awk
oder perl
zur Verfügung haben.
Das Rohrsystem war von Anfang an ein Teil von Unix. Wenn ein Prozess in Ihrer Pipeline beendet wird, möchten Sie normalerweise, dass alle Programme in der Pipeline beendet werden. Dies bedeutet, dass standardmäßig ein Prozess, der in eine Pipe schreibt, in der der Prozess am Leseende nicht mehr vorhanden ist, ein SIGPIPE
Signal erhält . Und wenn es dieses Signal blockiert, schlägt das write
immer noch mit einer besonderen Art von Fehler fehl, der darauf hinweist, dass das Rohr „gebrochen“ ist.
Die Standardbehandlung von beendet SIGPIPE
den Prozess, der es empfängt. Und wenn es nicht der "Kopf" der Pipeline ist, SIGPIPE
breitet sich das Ganze entlang der Kette aus.
Was Xcode beanstandet, ist, dass es ein Unterprogramm gestartet hat, um etwas mit einer dazu führenden Pipe zu tun, und dass dieses Unterprogramm unerwartet abgestorben ist und die Pipe gebrochen hat.
Eine "kaputte" Pipe ist eine Pipe, von der ein Ende close()
gelesen oder in die das andere geschrieben wird. Zum Beispiel im folgenden Shell-Befehl:
cat foo | less
Der cat
Prozess hält das schreibende Ende der Pipe und der less
Prozess das lesende. Wenn der Leseprozess die Pipe schließt, ist die Pipe unterbrochen (und daher unbrauchbar). Der Writer-Prozess erhält den Fehler "broken pipe" vom Betriebssystem.
cat
offensichtlich wird, sobald es fertig ist), sieht der Leser nur ein normales Dateiende.