我有带标题的bash shell脚本#!/bin/bash -e
。
当我运行脚本时,它将在grep
命令运行后被中断,但是当我删除参数时-e
,脚本可以正常运行。参数的含义是-e
什么?
我有带标题的bash shell脚本#!/bin/bash -e
。
当我运行脚本时,它将在grep
命令运行后被中断,但是当我删除参数时-e
,脚本可以正常运行。参数的含义是-e
什么?
-e
对于bash选项:serverfault.com/questions/391255/...。
Answers:
该-e
选项的意思是“如果任何管道以非零('错误')退出状态结束,请立即终止脚本”。因为grep
返回的退出状态是1
找不到任何匹配项,所以-e
即使没有真正的“错误” ,它也可能导致脚本终止。
如果您想保留该-e
选项,但又有一条grep
命令可能找不到有效的匹配项,则可以|| :
在该grep
命令后追加。这意味着“或者,如果grep
命令返回的退出状态为非零,则运行:
(不执行任何操作)”;因此,最终效果是禁用-e
该grep
命令。所以:
grep PATTERN FILE... || :
编辑补充:上述方法丢弃每一个错误:如果grep
回报率1
,因为它没有找到任何匹配,这是忽略不计,而且如果grep
回报率2
,因为有一个错误,就是忽视了,如果grep
不在路径(所以猛砸回报127
),这是被忽略-依此类推。因此,与其相比:
,最好使用命令检查结果代码并重新发出错误(如果不是)的命令1
。例如:
grep PATTERN FILE || (( $? == 1 ))
但这破坏了出口状态。通常,当失败的命令使用终止Bash脚本时-e
,该脚本将返回命令的退出状态,但是在上面的示例中,脚本将仅返回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=$?
。超级好用!
-e
选择,因此在这种情况下到底发生了什么?:(