2013-05-14 3 views
6

Warum read -t Timeout nicht beim Lesen von Rohr auf RHEL5 oder RHEL6?Warum `read -t` ist nicht in bash auf RHEL Zeitlimit?

Hier ist mein Beispiel, das auf meinen RHEL-Boxen aus dem Rohr wile Lese nicht Timeout:

tail -f logfile.log | grep 'something' | read -t 3 variable 

Wenn ich richtig bin read -t 3 soll nach 3 Sekunden Timeout?

Vielen Dank im Voraus.

Chris

GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu) 
+0

Nur für den Fall, können Sie 'alias' aufrufen und überprüfen, dass' read' nicht Alias ​​auf etwas anderes auf Ihrem System ist? –

+0

Fertig - alles klar. – Chris

+0

Sie wissen, dass 'Variable' nur in der Subshell gesetzt wird, in der der' read' Befehl ausgeführt wird, oder? Ihre Version von 'bash' hat nicht die Option' lastpipe', um den letzten Befehl einer Pipeline in der aktuellen Shell auszuführen. – chepner

Antwort

2

Während keine direkte Antwort auf Ihre Frage, müssen Sie so etwas wie

read -t 3 variable < <(tail -f logfile.log | grep "something") 

, um für den neu eingestellten Wert von variable sichtbar zu sein, nachdem die Pipeline abgeschlossen laufen. Überprüfen Sie, ob das Zeitlimit wie erwartet erreicht wird.


Da Sie einfach read als eine Möglichkeit des Austritts aus der Pipeline nach einer festgelegten Menge an Zeit verwenden, müssen Sie sich nicht über den Umfang der variable kümmern. Jedoch kann grep eine Übereinstimmung finden, ohne es innerhalb Ihrer Zeitüberschreitung aufgrund seiner eigenen internen Pufferung zu drucken. Sie können, dass deaktivieren (mit GNU grep zumindest), mit der --line-buffered Option:

tail -f logfile.log | grep --line-buffered "something" | read -t 3 

Eine weitere Option, falls vorhanden, ist der timeout Befehl als Ersatz für die read:

timeout 3 tail -f logfile.log | grep -q --line-buffered "something" 

Hier Wir töten tail nach 3 Sekunden und verwenden den Exit-Status grep in der üblichen Weise.

+0

+1. wollte das selbe vorschlagen. – mata

+0

Danke. Almost- 'read' beendet den Timeout-Wert, aber immer mit dem Code 142 - auch wenn 'grep' tatsächlich findet, was es finden soll. – Chris

+1

Sie möchten wahrscheinlich 'grep --line-buffered' verwenden, so dass' grep' ausgegeben wird, sobald eine Übereinstimmung gefunden wird. – chepner

0

ich nicht einen RHEL-Server das Skript jetzt zu testen, aber ich könnte wetten, als Lese auf Timeout wird beendet und arbeitet, wie es sollte. Versuchen Sie run:

grep 'something' | strace bash -c "read -t 3 variable" 

und Sie können das bestätigen.

+0

Sie haben recht - "lesen" beendet nach 'lesen (0, 0x7fff306fc50f, 1) =? ERESTARTSYS (Neustart) --- SIGALRM (Wecker) @ 0 (0) --- 'aber der Prozess hängt noch. – Chris

4

Die von chepner gegebene Lösung sollte funktionieren.

Eine Erklärung, warum Ihre Version nicht einfach ist: Wenn Sie eine Pipe wie Ihre erstellen, fließen die Daten durch die Pipe von links nach rechts. Wenn Ihr read jedoch abläuft, werden die Programme auf der linken Seite weiter ausgeführt, bis sie bemerken, dass die Pipe beschädigt ist, und das passiert nur, wenn sie versuchen, in die Pipe zu schreiben. diese

Ein einfaches Beispiel ist:

cat | sleep 5 

Nach fünf Sekunden wird das Rohr gebrochen werden, weil sleep verlassen wird, aber cat wird läuft trotzdem halten, bis Sie die Eingabetaste drücken.

In Ihrem Fall bedeutet dies, dass bis Ihr grep ein Ergebnis liefert, Ihr Befehl trotz Timeout weiterläuft.

Verwandte Themen