我试图运行
$ (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
终止该命令?
答案 0 :(得分:3)
您可以采取一些方法。
一种方法是将cat
和sleep
移动到while
语法的条件部分,这样一旦这些命令中的任何一个不成功,循环就会失败:< / p>
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
会导致( )
}。
顺便说一句 - 要么直接删除{ ...; }
,要么用T& T::operator+=( const T& ) {
// ... implementation ...
return *this;
}
T operator+( const T& lhs, const T& rhs ) {
T temp( lhs );
return temp += rhs;
}
替换它们是合适的,可以减少瞬态子壳的数量:虽然管道总是创建隐式子壳,但是没有使用语法的特殊原因(在某些情况下 - 有相关的细节是实现而不是标准定义)除了强制隐式的一个(s)之外还创建一个显式的子shell。
这是一个非常小的效率提升,但对于这个答案并不重要:如果你坚持使用原始括号但是以相同的方式修改了流控制结构,你会得到相同的行为。