`set -e` 和 `grep` 习惯用法,用于在未找到模式时防止过早退出 shell 脚本

Yeo*_*eng 17 grep bash gnu coreutils

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

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

我试图解决这个问题的方法如下:

(尝试 I)
如果set +o pipefail并使用类似的东西调用 grepgrep 'p' | wc -l那么我会得到所需的行为,直到未来的维护者启用pipefail. 另外,我喜欢启用pipefail所以这对我不起作用。

(试二)
使用一个sedawk和只打印匹配模式的行,然后wc匹配的行来测试匹配的模式。我不喜欢这个选项,因为使用sedtogrep似乎是解决我真正问题的方法。

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

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

gle*_*man 19

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

例子:grep杀死shell

$ bash
$ set -e
$ echo $$
33913
$ grep foo /etc/motd
$ echo $$
9233
Run Code Online (Sandbox Code Playgroud)

解决方案1:扔掉非零退出状态

$ bash
$ set -e
$ echo $$
34074
$ grep foo /etc/motd || true
$ echo $$
34074
Run Code Online (Sandbox Code Playgroud)

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

$ if ! grep foo /etc/motd; then echo not found; fi
not found
$ echo $$
34074
Run Code Online (Sandbox Code Playgroud)

从 bash 手册页讨论set -e

如果失败的命令是紧跟在whileuntil 关键字之后的命令列表的一部分、在ifelif保留字之后的测试的一部分、在&&?? 中执行的任何命令的一部分, 则 shell 不会退出。除了最后一个&&?? , 管道中除最后一个命令之外的任何命令,或者如果命令的返回值正在用! .

  • @schily 请指出在哪里可以找出 -e 的“正确”行为是什么,bash < 4 做了什么不同,以及在 POSIX 中发生了什么变化。 (2认同)