Joh*_*han 10 shell bash error-handling
当我阅读有关 $? 另一个问题浮现在脑海中。
是否有关于如何使用 $ 的最佳实践?在 bash 中?
让我们举个例子:
我们有一个线性脚本,我想知道所有命令都执行正常。你认为调用一个小函数(我们称之为“did_it_work”)来检查错误代码是否可以,如果不是就中断。
#!/bin/bash
function did_it_work {
code=$1
if [ "$code" -ne "0" ]
then
echo "Error failure: code $code "
exit 1
fi
}
dir=some/path
mkdir -p $dir
did_it_work $?
cd $dir
did_it_work $?
run_some_command
did_it_work $?
Run Code Online (Sandbox Code Playgroud)
这种方法当然意味着我必须手动解决问题(如果有的话)并重新运行脚本。
您认为这是一个好主意还是有其他一些最佳实践可以做到这一点?
/谢谢
Mik*_*kel 15
一种常见的方式是:
die() {
IFS=' ' # make sure "$*" is joined with spaces
# output the arguments if any on stderr:
[ "$#" -eq 0 ] || printf '%s\n' "$*" 1>&2
exit 1
}
Run Code Online (Sandbox Code Playgroud)
然后你像这样使用它:
mkdir -p some/path || die "mkdir failed with status $?"
Run Code Online (Sandbox Code Playgroud)
或者,如果您希望它包含退出状态,您可以将其更改为:
die() {
last_exit_status=$?
IFS=' '
printf '%s\n' "FATAL ERROR: $* (status $last_exit_status)" 1>&2
exit 1
}
Run Code Online (Sandbox Code Playgroud)
然后使用它会更容易一些:
mkdir -p some/path || die "mkdir failed"
Run Code Online (Sandbox Code Playgroud)
当它失败时,mkdir很可能已经发出了一条错误消息,因此第二个可能被视为多余的,您可以这样做:
mkdir -p some/path || exit # with the same (failing) exit status as mkdir's
mkdir -p some/path || exit 1 # with exit status 1 always
Run Code Online (Sandbox Code Playgroud)
(或die不加参数使用上述第一个变体)
以防万一你以前没见过command1 || command2,它运行command1,如果command1失败,它运行command2。
所以你可以像“创建目录或死亡”一样阅读它。
您的示例如下所示:
mkdir -p some/path || die "mkdir failed"
cd some/path || die "cd failed"
some_command || die "some_command failed"
Run Code Online (Sandbox Code Playgroud)
或者你可以dies在右边进一步对齐,这样主要代码就更明显了。
mkdir -p some/path || die "mkdir failed"
cd some/path || die "cd failed"
some_command || die "some_command failed"
Run Code Online (Sandbox Code Playgroud)
或者当命令行很长时在以下行:
mkdir -p some/path ||
die "mkdir failed"
cd some/path ||
die "cd failed"
some_command ||
die "some_command failed"
Run Code Online (Sandbox Code Playgroud)
此外,如果您要some/path多次使用该名称,请将其存储在一个变量中,这样您就不必一直键入它,并且可以在需要时轻松更改它。并且在将变量参数传递给命令时,请确保使用--选项分隔符,这样如果参数以-.
dir=some/path
mkdir -p -- "$dir" || die "Cannot make $dir"
cd -P -- "$dir" || die "Cannot cd to $dir"
some_command || die "Cannot run some_command"
Run Code Online (Sandbox Code Playgroud)
你可以像这样重写你的代码:
#!/bin/bash
function try {
"$@"
code=$?
if [ $code -ne 0 ]
then
echo "$1 did not work: exit status $code"
exit 1
fi
}
try mkdir -p some/path
try cd some/path
try run_some_command
Run Code Online (Sandbox Code Playgroud)
如果您实际上不需要记录错误代码,而只需要记录命令是否成功,您可以try()像这样进一步缩短:
function try {
if ! "$@"
then
echo "$1 did not work"
exit 1
fi
}
Run Code Online (Sandbox Code Playgroud)
如果您真的想exit出错并且正在使用 Bash,那么您还应该考虑set -e. 来自help set:
-e 如果命令以非零状态退出,则立即退出。
这当然不会为您提供 did_it_work() 函数的灵活性,但它是一种确保您的 bash 脚本在出现错误时停止的简单方法,而无需向您的新函数添加大量调用。
| 归档时间: |
|
| 查看次数: |
9628 次 |
| 最近记录: |