如果出现问题,我可以回滚 apt-get 升级吗?

Tot*_*tor 67 aptitude debian apt upgrade package-management

在启动aptitude upgradeor之前,有没有办法apt-get upgrade设置一些东西,以便您可以“轻松”将系统回滚到实际升级之前的“apt”状态,如果出现问题?

即,例如,重新安装在此过程中升级的旧版本软件包。

(编辑)一些提示:我知道etckeeper例如使用一些钩子,apt以便在apt安装或卸载软件包时通知它。我想可能有某种脚本可以保存新安装的软件包列表及其以前的版本号,以便能够从apt缓存 ( /var/cache/apt/archives) 中重新安装它们。还有checkinstall哪些可以跟踪文件修改...

有关如何正确实现这一目标的任何详细信息?

Chr*_*isW 58

我刚才不得不想出一个答案,因为apt-get upgradeDebian 服务器上的最后一个使得无法在 busybox 之外启动最新的内核,无法挂载 zfs 根分区。至少旧内核仍然可以启动,但与其他软件不兼容。因此需要回滚。

简短的回答 - 您可以使用以下命令:

$ apt-get -s install $(apt-history rollback | tr '\n' ' ')
Run Code Online (Sandbox Code Playgroud)

如果它做了你想要的删除-s并再次运行它。以下是我为使其正常工作而采取的步骤:

  1. 我暂时修剪了我/var/log/dpkg.log今天的升级离开

  2. 我安装的小脚本apt-history这里进入~/.bashrc就跑

    $ apt-history rollback > rollback.txt
    ...
    libzfs2:amd64=0.6.4-4~wheezy 
    zfsutils:amd64=0.6.4-4~wheezy 
    zfs-initramfs:amd64=0.6.4-4~wheezy
    ...
    
    Run Code Online (Sandbox Code Playgroud)
  3. 这提供了一个格式良好的版本化包列表,通过将其输入到apt-get install. 在文本编辑器中根据需要修剪此列表,然后运行(-s先进行试运行):

    $ apt-get -s install $(cat rollback.txt | tr '\n' ' ')
    $ apt-get install $(cat rollback.txt | tr '\n' ' ')
    
    Run Code Online (Sandbox Code Playgroud)

Apt 将对预期的降级发出警告。为防止此回滚被下一次升级覆盖,需要固定包,直到原始问题得到解决。例如:apt-mark hold zfsutils libzfs2 ...


function apt-history(){
    case "$1" in
      install)
            cat /var/log/dpkg.log | grep 'install '
            ;;
      upgrade|remove)
            cat /var/log/dpkg.log | grep $1
            ;;
      rollback)
            cat /var/log/dpkg.log | grep upgrade | \
                grep "$2" -A10000000 | \
                grep "$3" -B10000000 | \
                awk '{print $4"="$5}'
            ;;
      *)
            cat /var/log/dpkg.log
            ;;
    esac
}
Run Code Online (Sandbox Code Playgroud)

  • `apt-history rollback` 命令可以替换为类似 `awk '$3 ~ /upgrade/ {print $4"="$5}' dpkg.log`。 (3认同)
  • 修剪 dpkg.log 后,我收到一堆找不到版本的消息,即“E: Version '5.24.1-3+deb9u3' for 'libperl5.24' was not found”。我正在为 Raspian 使用 Debian Stretch。 (3认同)
  • 使用以下扩展名,它只匹配给定日期的升级(因此无需修改之前的日志):`awk '$1 == "2018-09-07" && $3 == "upgrade" {print $4"="$5 }' /var/log/dpkg.log` (2认同)
  • 不错的解决方案,但不知何故,我得到了未找到此特定版本的所有软件包... (2认同)

Fah*_*tha 8

日志文件/var/log/apt/history.log/var/log/apt/term.log是与您的描述最接近的内容:

我想可能有某种脚本可以保存新安装的软件包列表及其以前的版本号

history.logapt以下列格式给出每个动作的摘要列表:

Start-Date: 2013-06-21  16:05:05
Commandline: apt-get install rdiff-backup
Install: python-pyxattr:i386 (0.5.0-3, automatic), rdiff-backup:i386 (1.2.8-6), python-pylibacl:i386 (0.5.0-3, automatic
), librsync1:i386 (0.9.7-7, automatic)
End-Date: 2013-06-21  16:05:42
Run Code Online (Sandbox Code Playgroud)

特别是,它提供了新安装的软件包或已删除软件包的列表。此外,term.log显示在操作期间实际出现在终端上的内容,以便显示旧版本和新版本的包。来自我的随机样本history.log

Preparing to replace gnupg 1.4.10-4 (using .../gnupg_1.4.10-4+squeeze1_i386.deb) ...
Unpacking replacement gnupg ...
Processing triggers for install-info ...
Processing triggers for man-db ...
Processing triggers for doc-base ...
Processing 1 changed doc-base file(s)...
Registering documents with scrollkeeper...
Setting up gnupg (1.4.10-4+squeeze1) 
Run Code Online (Sandbox Code Playgroud)

apt不建议尝试自动回滚,但如果您使用日志,则应该可以手动执行此操作,除非失败的操作破坏了干扰 操作的某些内容apt,例如不一致的 dpkg 数据库。在这种情况下,您必须在继续之前解决问题。