2016-07-25 9 views
2

Ich versuchte some_script zu laufenkann kein Bash-Befehl töten, die in einer Schleife schläft

$ (while true; do cat some_small_file ; sleep 1; done) | some_script 

zu testen, aber some_script war nicht in meinem $PATH, so dass

some_script command not found 

Die

gedruckt komische Dinge sind, dass Bash nicht zurückgegeben wurde, und Ctrl-C tut nichts.

Ich habe sogar versucht sleep mit

ps -u maxb | grep sleep | cut -f1 -d " " | xargs kill -9 

in einem anderen Endgerät zu töten, aber das ist natürlich nur weiter auf die nächste Iteration.

Ist es möglich, Bash diesen Befehl zu beenden?

+1

Nebenbei, verwenden Sie 'pkill' anstelle von' ps | grep | xargs töten'. –

Antwort

3

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.

+1

Vielleicht weisen Sie darauf hin, dass, während die geschweiften Klammern potenziell nützlich sind für den Grund, den Sie sagen, 'während stuff; andere Dinge tun; fertig some_script ist ebenfalls eine gültige Syntax. – tripleee

+0

@tripleee, ausgezeichneter Anruf.Wirklich, ich sollte das stattdessen demonstrieren, da wir kein Präfix, Suffix oder ähnlichen Fall brauchen, wo ein Gruppierungsoperator benötigt wird. Bearbeitet entsprechend. –

Verwandte Themen