我尝试运行
$ (while true; do cat some_small_file ; sleep 1; done) | some_script
测试some_script
,但some_script
不在我的$PATH
中,因此打印
some_script command not found
奇怪的是,Bash
没有返回,而 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
。
顺便说一下——要么直接删除 ( )
,要么用 { ...; 替换它们。 }
适合作为潜在减少 transient 子 shell 数量的方法:虽然管道总是创建隐式子 shell,但没有特别的理由使用可能的语法(在某些情况下 - 有相关的细节是实现 - 而不是除了强制隐式子 shell 之外,还创建显式子 shell。
因此,这只是一个非常小的效率改进,但对于这个答案来说并不重要:如果您坚持使用原始括号,但以相同的方式修改流量控制结构,您会得到相同的行为。
关于linux - 无法终止循环休眠的 Bash 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38579035/