Es gibt ein paar Ansätze, die Sie hier machen können.
One ist sowohl cat
und sleep
in den bedingten Teil der while
Syntax zu bewegen, so dass die Schleife wird fehlschlagen, sobald eine dieser beiden Befehle nicht gelingt:
while cat some_small_file && sleep 1; do :; done | some_script
Eine ähnliche Möglichkeit ist, stellen eine explizite break
in die Schleife, konditioniert (wieder) auf solche failure:
while :; do cat some_small_file && sleep 1 || break; done | some_script
anzumerken, dass :
ist eine exakte Synonym für true
. (In jeder Shell, die ich gesehen habe - nicht nur Bash, sondern sogar Busybox Asche - sie sind buchstäblich durch die gleiche interne Funktion implementiert).
Beachten Sie auch, dass der wichtigste Teil dieser Lösung die Schleife wird beendet, wenn cat
ausfällt, nicht wenn sleep
versagt: Verlassen auf einem sleep
Fehler wird das kill
Problem lösen, aber auf einem cat
Ausfall austretende Handle der (viel wahrscheinlicher) Fall, dass some_script
hat verlassen und damit zu schreiben ist in einem SIGPIPE
resultiert.
Durch die Art und Weise - entweder das Entfernen des ()
s völlig oder sie mit { ...; }
ersetzen, um möglicherweise als eine Möglichkeit, geeignet ist, die Anzahl des transienten Subshells zu reduzieren: Während Pipelines immer impliziten Subshells schaffen, gibt es keinen besonderen Grund zu verwenden, Syntax, die (in einigen Fällen - es gibt relevante Details, die Implementierung sind anstatt Standard-definiert) erstellen Sie eine explizite Subshell zusätzlich zu den obligatorischen impliziten ein (s).
Es ist also eine sehr geringe Effizienzverbesserung, aber nicht wesentlich für diese Antwort: Sie würden das gleiche Verhalten erhalten, wenn Sie bei der ursprünglichen Klammer bleiben, aber die Flusskontrollkonstrukte auf die gleiche Weise modifiziert haben.
Nebenbei, verwenden Sie 'pkill' anstelle von' ps | grep | xargs töten'. –