简短答案
写
ps -ef | grep bar | { grep -v grep || test $? = 1; }
如果您正在使用set -e。
如果使用bash的pipefail选项(set -o pipefail),请记住将异常处理(||test)应用于grep管道中的每个对象:
ps -ef | { grep bar || test $? = 1; } | { grep -v grep || test $? = 1; }
在外壳程序脚本中,我建议您使用“ catch-1-grep”(c1grep)实用程序功能:
c1grep() { grep "$@" || test $? = 1; }
解释
grep的退出状态为0、1或2:[1]
0 表示选择了一条线
1 表示未选择任何行
2 表示发生错误
grep如果被信号中断(例如130SIGINT),它也可以返回其他代码。
由于我们只想忽略退出状态1,因此我们使用test了抑制特定退出状态的功能。
- 如果
grep返回0,test则不运行。
- 如果
grep返回1,test则运行并返回0。
- 如果
grep返回任何其他值,test则运行并返回1。
在最后一种情况下,脚本将由于set -e或立即退出set -o pipefail。但是,如果您根本不关心grep错误,那么您当然可以编写
ps -ef | grep bar | { grep -v grep || true; }
正如肖恩建议的。
Shell脚本中的[additional]用法
在shell脚本中,如果您使用grep很多,建议您定义一个实用程序函数:
c1grep() { grep "$@" || test $? = 1; }
这样,您的管道将再次变得简短而简单,而不会丢失set -eand的功能set -o pipefail:
ps -ef | c1grep bar | c1grep -v grep
仅供参考:
- 我称其
c1grep为强调仅是捕获退出状态1,仅此而已。
- 我本可以调用函数
grep(grep() { env grep "$@" ...; }),但我更喜欢使用一个不太混乱和更明确的名称c1grep。
[其他] ps+grep
所以,如果你想知道如何避免grep -v grep甚至| grep部分ps|grep可言,看看一些其他的答案; 但这有点离题了。
[1]grep联机帮助页
set -e不是bash特定的,而是适用于任何POSIX兼容的外壳(sh等)