Wie kann ich einen defekten Rohrfehler beheben?

Ich habe RVM kürzlich neu installiert (gemäß den Anweisungen unter http://rvm.io) nach einer Neuinstallation von Ubuntu 12.10, als ich ein SSD-Laufwerk bekam.

Nun, wenn ich tippe: type rvm | head -1

Ich erhalte folgenden Fehler:

rvm is a function
-bash: type: write error: Broken pipe

Aber wenn ich den Befehl sofort wiederhole, erhalte ich nur:

rvm is a function

Und es scheint alles in Ordnung ist? Was passiert da? Was kann ich tun um es zu beheben? Es passiert nicht immer. Es scheint sporadischer zu sein. Ich habe versucht, zu finden irgendeine Art von Muster dazu, aber noch nicht.

Author: terdon, 2013-02-20

4 answers

"Broken pipe" in dieser Situation zu sehen ist selten, aber normal.

Wenn Sie type rvm | head -1 ausführen, führt bash type rvm in einem Prozess aus, head -1 in einem anderen.1 Das stdout von type ist mit dem Ende "write" einer Pipe verbunden, das stdin von head mit dem Ende "read". Beide Prozesse laufen gleichzeitig.

Der head -1 - Prozess liest Daten aus stdin (normalerweise in Blöcken von 8 kB), druckt eine einzelne Zeile aus (gemäß der Option -1) und beendet sie, wodurch das "Lese" - Ende von das zu schließende Rohr. Da die Funktion rvm ziemlich lang ist (etwa 11 kB, nachdem sie von bash analysiert und rekonstruiert wurde), bedeutet dies, dass head beendet wird, während type noch einige kB Daten zu schreiben hat.

Da type versucht, in eine Pipe zu schreiben, deren anderes Ende geschlossen wurde – eine broken Pipe – gibt die write () - Funktion, die es aufgerufen hat, einen EPIPE-Fehler zurück, übersetzt als "Broken pipe". Zusätzlich zu diesem Fehler sendet der Kernel auch das SIGPIPE-Signal an type, wodurch der Prozess standardmäßig sofort beendet wird.

(Das Signal ist in interaktiven Shells sehr nützlich, da die meisten Benutzer nicht möchten, dass der erste Prozess weiterläuft und versucht, ins Nirgendwo zu schreiben. In der Zwischenzeit ignorieren nicht interaktive Dienste SIGPIPE – es wäre nicht gut für einen lang laufenden Daemon, bei einem so einfachen Fehler zu sterben -, sodass sie den Fehlercode sehr nützlich finden.)

Die Signalübertragung ist jedoch nicht 100% sofort, und es kann Fälle geben, in denen write() EPIPE zurückgibt und der Prozess wird für kurze Zeit fortgesetzt, bevor das Signal empfangen wird. In diesem Fall erhält type genug Zeit, um den fehlgeschlagenen Schreibvorgang zu bemerken, den Fehlercode zu übersetzen und sogar eine Fehlermeldung an stderr zu drucken, bevor er von SIGPIPE beendet wird. (Die Fehlermeldung lautet " - bash: type:", da type ein integrierter Befehl von bash selbst ist.)

Dies scheint auf Multi-CPU-Systemen häufiger zu sein, da der Prozess type und der Signallieferungscode des Kernels buchstäblich auf verschiedenen Kernen ausgeführt werden können zur gleichen Zeit.

Es wäre möglich, diese Nachricht zu entfernen, indem das eingebaute type (im Quellcode von bash) gepatcht wird, um es sofort zu beenden, wenn es ein EPIPE von der Funktion write() empfängt.

Es ist jedoch nichts, worüber man sich Sorgen machen muss, und es hängt in keiner Weise mit Ihrer Installation zusammen.

 62
Author: user1686,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2014-05-27 16:56:57

Sie können eine kaputte Pipe auf Kosten eines anderen Prozesses beheben, indem Sie tail -n +1 wie folgt in Ihre Pipe einfügen:

Typ rvm / Schwanz-n +1 / Kopf -1

Das +1 weist tail an, die erste Eingabezeile und alles, was folgt, zu drucken. Die Ausgabe ist genau so, als ob tail -n +1 nicht vorhanden wäre, aber das Programm ist intelligent genug, um die Standardausgabe zu überprüfen und die Pipe sauber zu schließen. Nicht mehr gebrochene Rohre.

 27
Author: Huuu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2015-11-17 17:39:42

Die Nachricht write error: Broken pipe bezieht sich auf einen Schreibprozess, der versucht, in eine Pipe zu schreiben, ohne dass Leser am Leseende dieser Pipe verbleiben, und auf den besonderen Umstand, dass das Signal SIGPIPE entweder vom aktuellen oder vom übergeordneten Prozess ignoriert wird. Wenn der übergeordnete Prozess SIGPIPE ignoriert hat, ist es dem untergeordneten Prozess nicht möglich, dies in einer nicht interacitiven Shell erneut rückgängig zu machen.

Es ist jedoch möglich, type rvm zu töten, wenn head -1 mit explicit beendet wird - Unterschalen. Auf diese Weise können wir type rvm, typepid an die head -1 Subshell senden und dann einen Trap für EXIT implementieren, um type rvm explizit zu töten.

trap "" PIPE        # parent process sets SIGPIPE to be ignored
bash                # start child process
export LANG=C
# create a fake rvm function
eval "
rvm() {
$(printf 'echo line of rvm code %s\n' {1..10000})
}
"

# rvm is a function
# bash: type: write error: Broken pipe
type rvm | head -1

# kill type rvm when head -1 terminates
# sleep 0: do nothing but with external command
( (sleep 0; type rvm) & echo ${!} ; wait ${!} ) | 
    (trap 'trap - EXIT; kill "$typepid"; exit' EXIT; typepid="$(head -1)"; head -1)
 2
Author: zancox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2017-05-23 12:41:51

Versuchen wir es mit yes, einem endlosen Prozess, der ja druckt...

Zuvor wurde der Prozess yes von SIGPIPE beendet, wenn das Limit erreicht wurde.

➜ set -o pipefail
➜ yes | head -n 1
y
➜ echo $?        
141

Meine Lösung

➜ yes | (head -n 1;dd status=none of=/dev/null)
y


# the process will still running and output to null

Sie können yes durch Ihr Programm ersetzen.

 1
Author: Miao1007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2020-03-10 15:08:27