如何防止 Debian 软件包安装过程中子进程失败并立即终止安装

如何防止 Debian 软件包安装过程中子进程失败并立即终止安装

我正在创建自己的 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/ elifwhile、 或 来“捕获”退出状态 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知道安装失败。

相关内容