我有标题的bash shell脚本#!/bin/bash -e.
当我运行脚本时,它会在grep命令运行后被中断,但是当我删除参数时-e,脚本可以正常运行.参数是什么意思-e?
rua*_*akh 91
该-e选项意味着"如果任何管道以非零('错误')退出状态结束,则立即终止脚本".由于grep返回退出状态,1当它找不到任何匹配时,-e即使没有真正的"错误" ,也可能导致终止脚本.
如果要保留该-e选项,但也有一个grep可能有效找不到匹配项|| :的grep命令,则可以附加到该命令.这意味着"或者,如果grep命令返回非零退出状态,则运行:(不执行任何操作)"; 所以净效应是禁用-e的grep命令.所以:
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时,它会关闭整个脚本.
| 归档时间: |
|
| 查看次数: |
43995 次 |
| 最近记录: |