我通常在我的Bash脚本中设置了-e
,但偶尔我想运行一个命令并获得返回值。
没有set +e; some-command; res=$?; set -e
舞蹈,我怎么能这样做?
答案 0 :(得分:54)
来自bash
手册:
如果失败的命令是&&amp ;;中执行的任何命令的一部分,则shell不会退出。或||列表[...]。
所以,就这样做:
#!/bin/bash
set -eu
foo() {
# exit code will be 0, 1, or 2
return $(( RANDOM % 3 ))
}
ret=0
foo || ret=$?
echo "foo() exited with: $ret"
示例运行:
$ ./foo.sh
foo() exited with: 1
$ ./foo.sh
foo() exited with: 0
$ ./foo.sh
foo() exited with: 2
这是规范的做法。
答案 1 :(得分:12)
作为替代
ans=0
some-command || ans=$?
答案 2 :(得分:6)
也许尝试在子shell中运行有问题的命令,比如这个?
res=$(some-command > /dev/null; echo $?)
答案 3 :(得分:-3)
使用包装函数执行命令:
function __e {
set +e
"$@"
__r=$?
set -e
}
__e yourcommand arg1 arg2
使用$__r
代替$?
:
if [[ __r -eq 0 ]]; then
echo "success"
else
echo "failed"
fi
在管道中调用命令的另一种方法,只需要引用管道。这样做是安全的。
function __p {
set +e
local __A=() __I
for (( __I = 1; __I <= $#; ++__I )); do
if [[ "${!__I}" == '|' ]]; then
__A+=('|')
else
__A+=("\"\$$__I\"")
fi
done
eval "${__A[@]}"
__r=$?
set -e
}
示例:
__p echo abc '|' grep abc
我实际上更喜欢这种语法:
__p echo abc :: grep abc
我可以用
做什么...
if [[ ${!__I} == '::' ]]; then
...