什么';bashshell命令行参数-e的含义是什么?
我有一个标题为什么';bashshell命令行参数-e的含义是什么?,bash,shell,Bash,Shell,我有一个标题为#的bashshell脚本/bin/bash-e 当我运行脚本时,它将在grep命令运行后中断,但当我删除参数-e时,脚本可以正常运行。参数-e的含义是什么?该-e选项表示“如果任何管道以非零('error')退出状态结束,请立即终止脚本”。由于grep在未找到任何匹配项时返回退出状态1,因此即使没有真正的“错误”,也会导致-e终止脚本 如果您想保留-e选项,但同时有一个grep命令,该命令可能无法有效地找到匹配项,则可以在grep命令后附加|;:。这意味着“或者,如果grep命令
#的bashshell脚本/bin/bash-e
当我运行脚本时,它将在
grep
命令运行后中断,但当我删除参数-e
时,脚本可以正常运行。参数-e
的含义是什么?该-e
选项表示“如果任何管道以非零('error')退出状态结束,请立即终止脚本”。由于grep
在未找到任何匹配项时返回退出状态1
,因此即使没有真正的“错误”,也会导致-e
终止脚本
如果您想保留-e
选项,但同时有一个grep
命令,该命令可能无法有效地找到匹配项,则可以在grep
命令后附加|;:
。这意味着“或者,如果grep
命令返回非零退出状态,则运行:
(不执行任何操作)”;因此,净效果是对grep
命令禁用-e
。因此:
grep PATTERN FILE... || :
编辑添加:上述方法会丢弃所有错误:如果
grep
返回1
,因为它没有找到匹配项,则忽略该错误;如果grep
返回2
,因为有错误,则忽略该错误;如果grep
不在路径中(因此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的评论)
此时,最好创建一个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
(注意使用命令
在其自身主体内绕过shell函数:我们希望函数调用常规程序grep
,而不是无限递归)。来自:
除了单字符shell命令行选项(请参见Set Builtin)外,还可以使用多个多字符选项
然后,如果我们看一下要说的话:
-e
如果管道(请参见管道)可能由单个简单命令(请参见简单命令)、括号内的子shell命令(请参见命令分组)或作为大括号内命令列表的一部分执行的其中一个命令(请参见命令分组)返回非零状态,请立即退出
因此,当您说
bash-e
时,如果脚本中的任何命令失败(即返回非零存在状态),则整个脚本立即失败。因此,您的grep
将返回一个非零值,因为它不匹配,如果您在运行bash时指定-e
,则会关闭整个脚本。@MitchWheat然而,情况确实如此,在这种情况下会发生什么(这确实不明显,但bash有一个-e
选项:。只多了一点。例如,当您找到以下内容时:[-e filepath]如果文件存在,则返回true。非常好。我已经开始使用您的建议捕获退出代码供以后使用:grep XXX file | | exitcode=$?
。超级方便!@dsummersl:酷,很高兴您喜欢它!您的评论启发我扩展了我的答案,并提供了一些您可能喜欢的潜在改进。说真的,谢谢您的改进。您喜欢的模式大纲很有启发性;它是一种很好的模式,可以防止意外的退出代码,同时忽略预期的退出代码……我可以肯定地看到,使用这种模式可以简化脚本的主要流程。@ruakh回答得很好,grep函数真的很有用。谢谢。只需再强调一点。例如,当您发现:如果文件存在,[-e filepath]将返回true。啊,是的,我怀疑这是来自set
,但想在手册中看到它。我想知道为什么我在man bash
中没有看到它,因为我直接去了列出的选项,错过了上面提到的段落“set builtin命令说明中记录的所有单字符shell选项,包括-o,都可以在调用shell时用作选项”。所有这些都有!