2016-07-01 10 views
1

Ich habe den folgenden Code in meinem Shell-Skript:bzip2 - Broken Rohr

bzip2 -dc $filename | head -10 > $output 

Manchmal diesen Fehler Ich erhalte (Debug-Ausgabe aktiviert):

+ head -10 
+ bzip2 -dc mylog.bz2 

bzip2: I/O or other error, bailing out. Possible reason follows. 
bzip2: Broken pipe 
     Input file = mylog.bz2, output file = (stdout) 

Es sieht aus wie head Befehl tritt abrupt auf und bzip2 empfängt SIGPIPE. Was kann ich damit machen? Ich muss sicher sein, dass die ersten 10 Zeilen in der $output Datei egal was sind. Es gibt keine Garantie, dass dies immer der Fall ist, wenn einer der Prozesse kläglich scheitert.

Antwort

1

Es sieht so aus, als ob head command abrupt beendet wird und bzip2 SIGPIPE empfängt.

Was erwarten Sie head tut? Es liest so viel von der Eingabe, wie es für die Ausgabe konfiguriert ist, und fährt dann herunter. Das ist so ziemlich von Design.

auch:

head -10 

Meine Version von head etwas erwartet, dass mehr wie

head -n10 
+0

Es gibt keinen Unterschied zwischen 'Kopf -10' und' Kopf -n10' AFAIK. Ja 'head' macht, was es tut, aber in korrekter Weise (normalerweise) ohne Fehler. Dieser Fehler tritt in der Produktionsumgebung auf und ich kann es bis jetzt nicht reproduzieren. – Lazin

+0

@Lazin zumindest, für meine Version von 'Kopf', erscheint die Nicht-' n'-Version nicht in der Dokumentation; aber ja, es funktioniert. –

+1

@Lazin der Unterschied zwischen '-10' und' -n 10' ist, dass das letztere in der [POSIX-Spezifikation] (http://pubs.opengroup.org/onlinepubs/009604599/utilities/head.html), so ist ist eher systemübergreifend übertragbar. –

2

Der bzip Befehl wird fehlschlagen, wenn der head Befehl beendet, nachdem seine Zeilen ausgegeben zu haben. Es gibt keinen Datenverlust. Der Befehl head hat seine Aufgabe erfüllt.

Wenn Sie darüber besorgt sind, können Sie den Anruf head mit einem sed Skript ersetzen, die die gleiche Sache tut:

bzip -dc "$filename" | sed -n '1,10p' >"$output" 

Dieser sed Skript wird alle Daten aus dem Rohr lesen, aber nicht beendet werden, wenn fertig mit Zeile 10.

+0

Danke für deine Antwort, vielleicht sollte ich alles so lassen wie es ist. Leider ist es in diesem Fall unmöglich, 'sed' zu verwenden, meine Datei ist viel zu groß. Die Dekompression dauert ungefähr zehn Minuten. – Lazin

+0

@Lazin Dann sind Sie am besten mit der Pipeline, wie es ist, ja. Leiten Sie Fehler einfach in den Bit-Bucket um, wenn Sie sie nicht sehen wollen. – Kusalananda

1

Sie können xargs für die Vermeidung von leeren Inhalt der head aus der Leitung verwenden, die die Ursache für SIGPIPE sein könnte. Auf diese Weise, selbst wenn bzip2 keine Ausgabe liefert, würden Sie keine Fehler sehen.

bzip2 -dc $filename | xargs -r head -10 > $output 

, wo die Option -r sagt

-r  If the standard input does not contain any nonblanks, do not run the command. Normally, the command is run once even if there is no input. This option is a GNU extension. 
+0

Was meintest du mit "leeren Inhalt"? Leere Datei oder leere Zeilen? Wie kann das 'SIGPIPE' verursachen? – Lazin

+0

@Lazin: Sorry für vage, mit der 'xargs' Option, auch wenn Sie keine Ausgabe von' bzip2' nach 'head' piped haben, wird der Befehl nicht fehlschlagen. In gewisser Weise wird head nur funktionieren, wenn es Inhalt hat – Inian

+0

Aber in meinem Fall ist es 'bzip2' derjenige, der versagt. Nicht der "Kopf". Und dieses kleine Skript funktioniert auch, wenn die Eingabedatei leer ist. Wenn die Eingabedatei beschädigt oder leer ist (nicht leeres Archiv, sondern Datei der Größe 0), liegt ein anderer Fehler vor, es wird eine Beschädigung festgestellt. – Lazin

Verwandte Themen