我正在创建自己的 Debian 软件包来安装 Apache Derby,作为安装的一部分,我希望运行配置脚本来设置一些默认用户。因此,在安装过程中,我启动 Apache Derby 网络服务器,然后使用类的“ping”命令测试它是否存在NetworkServerControl
。
为了允许服务器在短时间内启动,我预计“ping”命令会失败几次,因此我循环了大约 10 次,在每次 ping 之间暂停一秒钟:
let retry_count=0
echo "Testing for the Derby network server..."
$(which java) -Dderby.system.home=/srv/apache/derby -cp /usr/lib/apache/derby/derbynet.jar org.apache.derby.drda.NetworkServerControl ping -h localhost -p 1527 > /dev/null
until [[ $? -eq 0 ]]; do
echo "Network server not available."
let retry_count+=1
if [[ ${retry_count} -ge 10 ]]; then
echo "Network server was not available within ${retry_count} seconds. Terminating install." >&2
exit 1
fi
sleep 1
echo "Testing for the Derby network server..."
$(which java) -Dderby.system.home=/srv/apache/derby -cp /usr/lib/apache/derby/derbynet.jar org.apache.derby.drda.NetworkServerControl ping -h localhost -p 1527 > /dev/null
done
然而我发现第一个 ping 失败(返回 1)并导致整个安装过程失败:
In test_server_up function
Sun Sep 15 12:30:27 BST 2019 : Could not connect to Derby Network Server on host localhost, port 1527: Connection refused (Connection refused)
dpkg: error processing package derby-deb (--install):
installed derby-deb package post-installation script subprocess returned error exit status 1
我尝试将 ping 命令的结果分配给变量,但出现相同的错误。
是否有办法捕获子进程的结果并防止其终止安装?
答案1
我认为这是在您的安装后脚本中或从您的安装后脚本中调用的。
debian 打包约定是使用 运行 shell post-inst 等脚本set -e
,该脚本会在任何情况下退出并出现错误未捕获的非零退出代码。您可以使用例如||
或、&&
或if
/ elif
、while
、 或 来“捕获”退出状态 until
。详细信息请参见man bash
(搜索-e.*Exit
)。
例如
ping_count=0
until ping hostname || [ "$ping_count" -gt 5 ]; do
sleep 1 # or whatever
ping_count+=1 # non-posix. won't work with dash.
done
set +e
在 ping 之前尝试(或任何其他可能返回您知道的错误代码的命令)不关心)然后返回到set -e
之后。
注:我非常强烈建议反对只是完全摆脱set -e
。如果安装后的任何其他程序返回错误代码,您(以及安装该软件包的任何人)确实想知道它,并且您确实想dpkg
知道安装失败。