![如何返回退出代码?错误:返回:读取:需要数字参数](https://linux22.com/image/33755/%E5%A6%82%E4%BD%95%E8%BF%94%E5%9B%9E%E9%80%80%E5%87%BA%E4%BB%A3%E7%A0%81%EF%BC%9F%E9%94%99%E8%AF%AF%EF%BC%9A%E8%BF%94%E5%9B%9E%EF%BC%9A%E8%AF%BB%E5%8F%96%EF%BC%9A%E9%9C%80%E8%A6%81%E6%95%B0%E5%AD%97%E5%8F%82%E6%95%B0.png)
这是我的脚本的简化版本。我的问题是,apt-get
在这种情况下如何返回退出代码?
#!/bin/bash
install_auto() {
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
return $(sudo apt-get install --assume-yes $@)
fi
return 1
}
echo "installing $@"
install_auto "$@"
echo $?
echo "finished"
exit 0
输出是:
./install_test.sh: line 5: return: Reading: numeric argument required
更新:我想出了一些有效的方法:
return $(sudo apt-get install --assume-yes "$@" >/dev/null 2>&1; echo $?)
这是一个好方法吗?
答案1
Bashreturn()
只能返回数字参数。无论如何,默认情况下,它将返回上次运行命令的退出状态。所以,你真正需要的是:
#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
sudo apt-get install --assume-yes $@
fi
}
您不需要显式设置要返回的值,因为默认情况下函数将返回$?
。但是,如果第一个apt
命令失败并且您没有进入循环,则这将不起作用if
。为了使其更加健壮,请使用:
#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
ret=$?
if [ $ret -eq 0 ] ; then
## If this is executed, the else is ignored and $? will be
## returned. Here, $?will be the exit status of this command
sudo apt-get install --assume-yes $@
else
## Else, return the exit value of the first apt-get
return $ret
fi
}
一般规则是,为了让函数返回特定作业的退出状态,而不一定是它运行的最后一个作业,您需要将退出状态保存到变量并返回该变量:
function foo() {
run_a_command arg1 arg2 argN
## Save the command's exit status into a variable
return_value= $?
[the rest of the function goes here]
## return the variable
return $return_value
}
编辑:实际上,正如 @gniourf_gniourf 在评论中指出的那样,您可以使用以下方法大大简化整个事情&&
:
install_auto() {
apt-get -h > /dev/null 2>&1 &&
sudo apt-get install --assume-yes $@
}
该函数的返回值将是以下之一:
- 如果
apt-get -h
失败,它将返回退出代码 - 如果
apt-get -h
成功,它将返回 的退出代码sudo apt-get install
。
答案2
为了完整起见,这是我的实际函数,按照 @terdon 和 @gniourf_gniourf 的建议进行了一些修改:
install_auto() {
if [ ! $# -gt 0 ] ; then
echo "usage: $0 package_name [package_name ...]"
fi
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
if [ -f "$@" ] || [[ "$@" =~ '/' ]] ; then
sudo gdebi -n "$@"
return $?
else
sudo apt-get install --assume-yes "$@"
return $?
fi
fi
zypper help > /dev/null 2>&1
if [ $? -eq 0 ] ; then
sudo zypper --non-interactive --no-gpg-checks --quiet install --auto-agree-with-licenses "$@"
return $?
fi
#may check other package managers in the future
echo "ERROR: package manager not found"
return 255
}
我很感激任何进一步的建议。