bash shell命令行参数-e的含义是什么?
我有作为bash shell脚本与标题#!/bin/bash -e
。
当我运行这个脚本时, grep
命令运行后会中断,但是当我删除参数-e
,脚本就可以正常运行了。 参数-e
的含义是什么?
-e
选项表示“如果任何pipe道以非零('错误')退出状态结束,则立即终止脚本”。 由于grep
在没有find任何匹配的情况下返回1的退出状态,所以即使没有真正的“错误”,也会导致-e
终止脚本。
如果你想保持-e
选项,但也有一个可能有效地找不到匹配的grep
命令,你可以追加|| :
|| :
到grep
命令。 这意味着“或者,如果grep
命令返回一个非零的退出状态,运行:
什么都不做)”; 所以最终效果是禁用-e
为grep
命令。 所以:
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整个脚本。