bash shell命令行参数-e的含义是什么?

我有作为bash shell脚本与标题#!/bin/bash -e

当我运行这个脚本时, grep命令运行后会中断,但是当我删除参数-e ,脚本就可以正常运行了。 参数-e的含义是什么?

-e选项表示“如果任何pipe道以非零('错误')退出状态结束,则立即终止脚本”。 由于grep在没有find任何匹配的情况下返回1的退出状态,所以即使没有真正的“错误”,也会导致-e终止脚本。

如果你想保持-e选项,但也有一个可能有效地找不到匹配的grep命令,你可以追加|| : || :grep命令。 这意味着“或者,如果grep命令返回一个非零的退出状态,运行:什么都不做)”; 所以最终效果是禁用-egrep命令。 所以:

 grep PATTERN FILE... || : 

编辑添加:上面的方法丢弃每一个错误:如果grep返回1因为它发现没有匹配,这被忽略,而且如果grep返回2因为有错误,这被忽略,如果grep不在path中Bash返回127 ), 这是忽略 – 等等。 所以,而不是:使用一个命令来检查结果代码,如果它不是1的话,重新发出错误可能会更好。 例如:

 grep PATTERN FILE || (( $? == 1 )) 

但是这破坏了退出的状态; 通常,当失败的命令用-e终止Bash脚本时,脚本将返回命令的退出状态,但在上面的示例中,脚本将仅返回1 。 如果(并且只有)我们关心这一点,我们可以通过写这样的东西来解决它:

 grep PATTERN FILE || exit_code=$? if (( exit_code > 1 )) ; then exit $exit_code fi 

(第一行c / o dsummersl的评论)。

在这一点上,最好创build一个shell函数来为我们处理这个问题:

 function grep_no_match_ok () { local exit_code grep "$@" || exit_code=$? return $(( exit_code == 1 ? 0 : exit_code )) } 

(注意使用return而不是exit ;我们会让-e在适当的时候处理退出); 这样,我们可以写:

 grep_no_match_ok PATTERN FILE # won't kill script if no matches are found 

实际上,由于我们很可能希望在这个脚本中使用这个函数来处理所有grep ,所以我们实际上可以命名为grep

 function grep () { local exit_code command grep "$@" || exit_code=$? return $(( exit_code == 1 ? 0 : exit_code )) } grep PATTERN FILE # won't kill script if no matches are found 

(注意使用command绕过shell函数在自己的内部:我们希望函数调用正则程序grep ,而不是无限recursion)。

从精美的手册 :

除了单字符shell命令行选项外(请参阅Set Builtin),还有几个可供使用的多字符选项。

然后,如果我们看看有什么不得不说:

-e
如果一个stream水线(参见stream水线)可以立即退出,这个stream水线可以由一个简单的命令(参见简单命令),一个用圆括号括起来的子shell命令(参见命令分组),或者作为命令列表的一部分执行的一个命令大括号(请参阅命令分组)返回一个非零状态。

所以当你说bash -e ,如果脚本中的任何命令失败(即返回一个非零的存在状态),那么整个脚本立即失败。 所以你的grep返回一个非零值,因为它不匹配,如果你在运行bash时指定了-e ,那就closures整个脚本。