set -e和grep惯用法防止未找到模式时从shell脚本过早退出


15

需要帮助-在GNU / LINUX bash上的shell脚本中:

我总是用set -e。通常,grep如果grep退出状态1表明未找到模式,我通常不希望脚本终止执行。

我尝试解决此问题的方法如下:

(尝试I)
如果set +o pipefail使用类似的方法调用grep,grep 'p' | wc -l那么我将获得所需的行为,直到将来的维护者启用为止pipefail。另外,我喜欢启用,pipefail因此这对我不起作用。

(尝试II)
使用sedawk仅打印匹配模式的行,然后使用wc匹配行测试匹配的模式。我不喜欢这样的选择,因为使用sedgrep似乎是我的真实问题的方法。

(尝试III)
这是我最不喜欢的-类似于:set +e; grep 'p'; set-e

任何见解/习惯用语将不胜感激-谢谢。

Answers:


19

您可以将grep置于if条件中,或者如果您不关心退出状态,请添加|| true

示例:grep杀死外壳

$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233

解决方案1:丢弃非零退出状态

$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074

解决方案2:显式测试退出状态

$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074

在bash手册页中讨论set -e

如果失败的命令是在一会儿直到 关键字之后紧随其后的命令列表的一部分,在ifelif保留字之后的测试的一部分,在&&││列表中执行的任何命令的一部分( 除了在最后一个&&││之后的命令,管道中除最后一个命令之外的任何命令,或者如果该命令的返回值用反转


由于长期以来bash未能正确实现-e,因此文档可能不正确。由于该文本似乎与bash-3.x手册页相同,请注意:bash4.0之前的所有bash版本均未正确实现-e。
2015年

还要注意,由于POSIX标准也是错误的,我们在2009年
schily 2015年

1
@schily请提供指向,以指出-e的“正确”行为是什么,bash <4有何不同之处以及在POSIX中有何更改。
zwol

bash-3中的错误基本上使它无法使用,make因为它并不总是在出现错误时退出。对于相关的POSIX讨论,您可能想查看austingroupbugs.net
schily 2015年

@schily请您更具体吗?
zwol 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.