有没有办法在 Debian/Ubuntu 系统上使用 apt/apt-get 安装的软件包进行快照,然后稍后回滚到该快照?
我的用例如下:我想编写一个脚本来构建一个具有大量构建依赖项的程序。我想在脚本开始时安装这些依赖项。其中一些依赖项可能已经安装,在这种情况下,一些安装将不需要操作。构建程序后,我想让系统恢复到构建之前的状态,即我想卸载脚本安装的内容,但其他内容保持不变。
换句话说,我想将 apt 回滚到快照!
我正在想象这样的事情:
magic-command-that-writes-apt-snapshot my-packages.txt
apt install gcc texlive fortran75 cobol60 qbasic fftw
./configure && && make && make install
magic-command-that-rollsback-to-apt-snapshot my-packages.txt
也许通过解析可以实现这一点/var/log/apt/history.log
,但这似乎非常脆弱。
一些细节可能会使事情变得更简单或更复杂:
- 我想要一个对于机器的初始状态具有鲁棒性的通用解决方案,但我可以保证我的脚本只包含一个
apt install
命令(不是几个,不是dist-upgrade
,不是build-deps
)。 - 在这种情况下,我并不担心 apt 命令升级。对我而言,这是一个良性副作用。回滚不应该卸载它们,但如果不降级它们,那就没问题了。
- 该脚本需要保持非交互式(它恰好在docker build中运行)。
- 我想避免“附带损害”。特别是,我不能仅仅因为包 B 是由脚本安装的,包 B 依赖于包 A,而包 A 除了包 B 之外没有其他依赖项,就假设包 A 应该被卸载。也许包 A 已经安装了!换句话说,只有当包是由脚本安装的,才应该卸载它们。它们是否有依赖项并不重要。(这个要求是这个问题不是重复的原因类似这样的问题,如果我理解正确的话。)
答案1
您可以尝试使用‘apt-rollback’您可以在这里找到脚本:
https://gitlab.com/fabio.dellaria/apt-rollback
wget https://gitlab.com/fabio.dellaria/apt-rollback/-/raw/master/apt-rollback.sh && chmod +x ./apt-rollback.sh
使用以下命令:
./apt-rollback.sh --last
Usage: apt-rollback [--last] [--remove/--reinstall package-name] [--help] --last Undo the last APT command Supports the undo of the only Install, Remove and Purge commands --remove Remove an INSTALLED package and related configuration files Removing also all its first installed dependencies --reinstall Reinstall a REMOVED package, and all its first installed dependences Reproducing exactly its first installation --help Print the help
您可以在此处观看一个小视频演示: apt-rollback 视频演示
答案2
内置选项
据我所知,apt/apt-get 没有内置函数可以完成你正在寻找的功能。快照 - Debian它似乎做了类似的事情,尽管我认为它不能完全满足您的要求。
备择方案
这些是一些需要考虑的选项,因为我没有看到使用 Ubunut 的硬性要求。
Solus(eopkg)
虽然与 Ubuntu 没有特别的关系,但我知道 Solus 在他们的包管理器中提供了这个功能:eopokg文档
例子
引用提供的链接:
历史
您可以使用以下命令查看 eopkg 的历史记录:
sudo eopkg history
回滚
要回滚系统,首先使用上面的 history 命令检查事务/操作编号。然后,我们使用以下命令:
sudo eopkg history -t number
在这种情况下,数字是您要更改的操作之前的操作。因此,如果数字是 100,那么您将使用 99。
Yum(Fedora / CentOS / RHEL)
Yum 确实内置了这种功能。你可以在他们的官方文档中找到这一点,这里和这里
例子
参考他们的文档你可以:
sudo yum history list all
找到您想要撤消的交易并获取更多信息。
sudo yum history info <transaction_ID>
然后撤消它:
sudo yum undo <transaction_ID>
答案3
Apt 没有快照功能。它通常不需要这个功能。它已经完成了你想要的大部分功能。
您的 Ubuntu 系统确实具有出色的备份功能,通常用于数据,但也可以用于软件包。它默认安装在所有 *buntu 桌面系统上。
与 debs 相比,Snaps 更适合用于安装(和卸载)大型复杂软件(可能包括软件包和编译的二进制文件)。
编辑:OP 的评论澄清了用例——我们不知道哪些软件包已经安装,我们希望删除的软件包与安装的软件包相匹配。幸运的是,apt 也可以做到这一点。以下是两种不同的方法:
- 使用 apt-marking。Apt 会跟踪您指定的安装 vs 哪些包作为依赖项引入。您可以更改该跟踪。通常,顶级包应被 apt 标记为“手动”,所有依赖项应被 apt 标记为“自动”
像平常一样安装:sudo apt install foo bar baz
这 apt 将把所有三个包标记为“手动”安装。
- 除非您指定删除它们,否则 Apt 不会删除它们。
- 被引入的依赖项
libfoo
将被适当标记为“自动”。 - 如果
bar
是已经安装后,它将不会再次安装,但它的 apt-mark 将从“自动”更改为“手动”,因为有人希望安装它。
您无法安全地使用,apt remove foo bar baz
因为删除bar
也会删除之前依赖的所有内容bar
。所以这里有一个技巧:将 apt-marking 改回“auto”
sudo apt-mark auto foo bar baz // Make packages eligible for autoremove
sudo apt autoremove // Remove Foo and Baz (and their dependencies)
// Since something else "manual" still depends upon Bar, don't remove it.
- Apt 日志是什么实际上安装在 /var/log/apt。解析该日志以确定要删除的列表。