【问题标题】:What's the meaning of the parameter -e for bash shell command line?bash shell命令行的参数-e是什么意思?
【发布时间】:2012-03-31 01:18:46
【问题描述】:

我有一个带有标题 #!/bin/bash -e 的 bash shell 脚本。

我运行脚本的时候,在grep命令运行后会中断,但是当我去掉参数-e之后,脚本就可以正常运行了。参数-e是什么意思?

【问题讨论】:

  • @MitchWheat 但是有no -e option for bash 那么,在这种情况下到底发生了什么? :(
  • 确实不是很明显,但是 bash 的-e 选项:serverfault.com/questions/391255/…
  • 只多了一点。例如,当您找到以下内容时: [ -e filepath ] 如果文件存在,则返回 true。

标签: bash shell


【解决方案1】:

-e 选项表示“如果任何管道以非零('错误')退出状态结束,则立即终止脚本”。由于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 dsummersl 的评论)。

此时,最好创建一个 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,而不是无限递归)。

【讨论】:

  • 非常好。我已经开始使用您的建议来捕获退出代码以供以后使用:grep XXX FILE || exitcode=$?。超级好用!
  • @dsummersl:很酷,很高兴你喜欢它!您的评论启发我用您可能喜欢的一些潜在改进来扩展我的答案。
  • 说真的,谢谢。你勾勒的模式很有启发性;这是一个很好的模式,可以防止意外退出代码,同时忽略预期的退出代码......我绝对可以看到使用这种模式来简化我的脚本的主要流程。
  • @ruakh 很好的答案,grep 函数真的很有用。谢谢。
  • 只多了一点。例如,当您找到以下内容时: [ -e filepath ] 如果文件存在,则返回 true。
【解决方案2】:

来自fine manual

除了单字符 shell 命令行选项(请参阅 The Set Builtin)之外,您还可以使用多个多字符选项。

然后,如果我们看看 set 不得不说的话:

-e
如果管道(请参阅管道)可能包含单个简单命令(请参阅简单命令)、括在括号中的子 shell 命令(请参阅命令分组)或作为命令列表的一部分执行的命令之一,则立即退出大括号(请参阅命令分组)返回非零状态。

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

【讨论】:

  • 啊,是的,我怀疑这是来自set,但想在手册中看到它。我想知道为什么我在man bash 中没有看到它,这是因为我直接进入列出的选项并错过了说 “所有单字符 shell 选项记录在 set builtin 的描述中的段落命令,包括 -o,可以在调用 shell 时用作选项”。 全部都在那里!
猜你喜欢
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 2016-05-15
  • 2016-12-01
  • 2016-12-22
相关资源
最近更新 更多