无法终止循环休眠的 Bash 命令
Can't kill a Bash command that sleeps in a loop
我试过运行
$ (while true; do cat some_small_file ; sleep 1; done) | some_script
测试 some_script
,但 some_script
不在我的 $PATH
中,因此打印
some_script command not found
奇怪的是 Bash
没有 return,而 Ctrl-C
什么也没做。
我什至试过用
杀死sleep
ps -u maxb | grep sleep | cut -f1 -d " " | xargs kill -9
在另一个终端中,但那当然只是继续到下一个循环迭代。
是否可以让 Bash
终止该命令?
您可以在此处采取一些方法。
一个是将 cat
和 sleep
都移动到 while
语法的条件部分,这样一旦这些命令中的任何一个不成功,循环就会失败:
while cat some_small_file && sleep 1; do :; done | some_script
一个类似的选项是将显式 break
放入循环中,(再次)以此类失败为条件:
while :; do cat some_small_file && sleep 1 || break; done | some_script
请注意 :
是 true
的同义词。 (在我见过的每个 shell 中——不仅是 bash,甚至是 Busybox ash——它们实际上是由相同的内部函数实现的。
另请注意,此解决方案最重要的部分 是在 cat
失败时退出循环,而不是 sleep
失败时退出:在 sleep
失败将解决 kill
问题,但退出 cat
失败将处理(更有可能) some_script
已退出的情况,因此写入它会导致SIGPIPE
.
顺便说一下——直接删除 ( )
或用 { ...; }
替换它们是适当的,可以减少瞬态子 shell 的数量:虽然管道总是创建隐式 subshells,没有特别的理由使用可能(在某些情况下——有相关细节是实现而不是标准定义的)创建显式 subshell 的语法除了强制隐含的。
因此,这是一个非常小的效率改进,但对于这个答案来说并不是必需的:如果您坚持使用原始括号但以相同的方式修改流控制结构,您会得到相同的行为。
我试过运行
$ (while true; do cat some_small_file ; sleep 1; done) | some_script
测试 some_script
,但 some_script
不在我的 $PATH
中,因此打印
some_script command not found
奇怪的是 Bash
没有 return,而 Ctrl-C
什么也没做。
我什至试过用
杀死sleep
ps -u maxb | grep sleep | cut -f1 -d " " | xargs kill -9
在另一个终端中,但那当然只是继续到下一个循环迭代。
是否可以让 Bash
终止该命令?
您可以在此处采取一些方法。
一个是将 cat
和 sleep
都移动到 while
语法的条件部分,这样一旦这些命令中的任何一个不成功,循环就会失败:
while cat some_small_file && sleep 1; do :; done | some_script
一个类似的选项是将显式 break
放入循环中,(再次)以此类失败为条件:
while :; do cat some_small_file && sleep 1 || break; done | some_script
请注意 :
是 true
的同义词。 (在我见过的每个 shell 中——不仅是 bash,甚至是 Busybox ash——它们实际上是由相同的内部函数实现的。
另请注意,此解决方案最重要的部分 是在 cat
失败时退出循环,而不是 sleep
失败时退出:在 sleep
失败将解决 kill
问题,但退出 cat
失败将处理(更有可能) some_script
已退出的情况,因此写入它会导致SIGPIPE
.
顺便说一下——直接删除 ( )
或用 { ...; }
替换它们是适当的,可以减少瞬态子 shell 的数量:虽然管道总是创建隐式 subshells,没有特别的理由使用可能(在某些情况下——有相关细节是实现而不是标准定义的)创建显式 subshell 的语法除了强制隐含的。
因此,这是一个非常小的效率改进,但对于这个答案来说并不是必需的:如果您坚持使用原始括号但以相同的方式修改流控制结构,您会得到相同的行为。