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

Sam*_* Ho 67 bash shell

我有标题的bash shell脚本#!/bin/bash -e.

当我运行脚本时,它会在grep命令运行后被中断,但是当我删除参数时-e,脚本可以正常运行.参数是什么意思-e

rua*_*akh 91

-e选项意味着"如果任何管道以非零('错误')退出状态结束,则立即终止脚本".由于grep返回退出状态,1当它找不到任何匹配时,-e即使没有真正的"错误" ,也可能导致终止脚本.

如果要保留该-e选项,但也有一个grep可能有效找不到匹配项|| :grep命令,则可以附加到该命令.这意味着"或者,如果grep命令返回非零退出状态,则运行:(不执行任何操作)"; 所以净效应是禁用-egrep命令.所以:

grep PATTERN FILE... || :
Run Code Online (Sandbox Code Playgroud)

编辑添加:上面的方法丢弃每个错误:如果grep返回1因为它找不到匹配,那就被忽略了,但是如果grep返回2因为有错误,那就被忽略了,如果grep不在路径中(所以Bash返回127),那就是忽略 - 依此类推.因此,:使用检查结果代码的命令并重新发出错误(如果不是这样的话)可能更好1.例如:

grep PATTERN FILE || (( $? == 1 ))
Run Code Online (Sandbox Code Playgroud)

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

grep PATTERN FILE || exit_code=$?
if (( exit_code > 1 )) ; then
    exit $exit_code
fi
Run Code Online (Sandbox Code Playgroud)

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

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

function grep_no_match_ok () {
    local exit_code
    grep "$@" || exit_code=$?
    return $(( exit_code == 1 ? 0 : exit_code ))
}
Run Code Online (Sandbox Code Playgroud)

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

grep_no_match_ok PATTERN FILE     # won't kill script if no matches are found
Run Code Online (Sandbox Code Playgroud)

实际上,由于我们很可能希望将此函数用于此脚本中的所有实例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
Run Code Online (Sandbox Code Playgroud)

(注意使用command绕过它自己体内的shell函数:我们希望函数调用常规程序grep,而不是无限地递归).


mu *_*ort 16

精细手册:

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

然后,如果我们看看有什么set话要说:

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

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

  • 啊,是的,我怀疑这是来自“set”,但想在手册中看到它。我想知道为什么我没有在`man bash`中看到它,这是因为我直接转到列出的选项并错过了“*”set内置命令的描述中记录的所有单字符shell选项的段落,包括 -o,可以在调用 shell 时用作选项”。* 全部都在那里! (3认同)