0%

Linux服务器dpkg报错问题解决

🧩 问题背景

在我的 Ubuntu 系统中,无论是执行:

1
2
3
4
5
6
7
sudo apt install <package>
````

还是:

```bash
sudo dpkg --configure -a

每次涉及 dpkg 调用时,系统都会在最后阶段报出相同的错误信息:

1
2
3
4
5
6
7
8
Setting up openssh-server (1:8.2p1-4ubuntu0.13) ...
rescue-ssh.target is a disabled or a static unit, not starting it.
/usr/sbin/invoke-rc.d: 308: test: x: unexpected operator
invoke-rc.d: initscript ssh, action "restart" failed.
dpkg: 处理软件包 openssh-server (--configure)时出错:
已安装 openssh-server 软件包 post-installation 脚本 子进程返回错误状态 1
在处理时有错误发生:
openssh-server

表面上似乎只是 SSH 相关的警告,但它会导致 所有 apt/dpkg 命令退出码非 0,从而影响系统更新、软件安装、甚至 Docker 构建过程。


🧠 问题排查过程

一、确定 SSH 实际状态

首先查看 SSH 服务状态:

1
systemctl status ssh

结果显示:

1
2
3
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running)

可以确定——SSH 服务本身完全正常运行
说明问题并不是服务启动失败,而是安装后脚本执行返回了错误状态。


二、查看 dpkg 后安装脚本

dpkg 的安装、配置流程中会调用 /var/lib/dpkg/info/<package>.postinst
针对 openssh-server,我们打开:

1
sudo nano /var/lib/dpkg/info/openssh-server.postinst

在文件的末尾,找到类似这一行:

1
invoke-rc.d ssh $_dh_action

这里的 $_dh_action 一般是 restartstartreload
该行调用的是 /usr/sbin/invoke-rc.d,由它来执行 SSH 服务的重启。

而正是这一步返回了非零状态(exit code 1),导致 dpkg 报错。


🧰 解决方案

为了让 dpkg 在执行此处时即使失败也能继续正常返回,我们在命令后添加 || true

1
invoke-rc.d ssh $_dh_action || true

这表示:

“即使前面的命令执行失败,也不要将整个脚本判定为失败。”

保存退出后,再执行:

1
sudo dpkg --configure -a

这一次输出正常,没有再出现报错。

再运行:

1
sudo apt install -f

或:

1
sudo apt upgrade

都能顺利完成。


✅ 验证结果

  1. SSH 服务状态依旧正常:

    1
    systemctl status ssh

    输出:

    1
    Active: active (running)
  2. dpkg 状态干净:

    1
    dpkg -l | grep openssh-server

    输出:

    1
    ii  openssh-server  1:8.2p1-4ubuntu0.13  amd64  secure shell (SSH) server, for secure access from remote machines
  3. apt/dpkg 不再受阻,系统升级恢复正常。


🧩 原因分析

这个问题实质上是由于:

  • /usr/sbin/invoke-rc.d 脚本中的兼容性 bug(使用 == 等语法在 dash 下报错),
  • 或者某些运行环境中 systemd 启动 SSH 时返回状态非 0。

虽然服务本身成功运行,但 postinst 脚本没有忽略非零返回值,从而让 dpkg 误认为失败。


💡 为什么 “|| true” 是安全的

postinst 脚本的主要作用是在安装或升级时触发服务刷新
即使 invoke-rc.d 返回失败:

  • 不影响 SSH 本身(systemd 仍会自动管理服务),
  • 不影响配置文件、密钥等资源,
  • 只会让 dpkg 终止于非零状态。

加上 || true 后可以安全地忽略这种假性错误,
在确保系统完整性的同时恢复 dpkg 的正常运行逻辑。


🧾 总结

项目 说明
问题现象 所有 apt/dpkg 命令末尾都会因 openssh-server 报错而退出
服务状态 SSH 实际运行正常
根本原因 postinst 调用 invoke-rc.d 时返回 1
最终修复 修改 /var/lib/dpkg/info/openssh-server.postinst,将 invoke-rc.d ssh $_dh_action 改为 `invoke-rc.d ssh $_dh_action true`
修复效果 dpkg 恢复正常,系统升级和安装不再出错

🧠 经验与启示

  1. apt/dpkg 的脚本错误并不一定意味着服务坏了,
    很多时候只是“返回值不符合预期”。
  2. 可以通过修改 /var/lib/dpkg/info/<pkg>.postinst 进行安全绕过。
  3. 如果未来系统更新覆盖此文件,可再次添加 || true
  4. 在容器(Docker)或无交互环境中尤其常见。

💬 结语

这个问题一开始看似 SSH 崩溃,
实则是 dpkg 对返回值“太认真”。
最终只是加上 || true,就让整个系统重新恢复了顺畅。

希望这篇记录能帮到你,也提醒未来的自己:
看清楚错误来源,不要慌,dpkg 只是有点“洁癖”。 😄