如何将已安装的软件包选择从一个 Fedora 实例复制到另一个实例?

max*_*zig 18 yum fedora dnf

我有一个 Fedora 系统 (A),我在那里安装了一些软件包。现在我想在另一台计算机 (B) 上安装 Fedora,并且我想在其上安装相同的软件包。

在 Debian 术语中,我想完成这样的事情:

$ dpkg --get-selections > pkg_sel_host_a  # on host_a
$ dpkg --set-selections < pkg_sel_host_a  # on host_b
Run Code Online (Sandbox Code Playgroud)

但老实说,我真的想要一种更好的方法来在新的 Fedora 19 系统 (B) 上选择相同的软件包:我只想从系统 A 安装在dnf install(或yum install)命令行中明确提到的软件包 - 而不是那些作为依赖项安装的!

为什么?因为可能依赖项已更改 - 我不想在新系统上安装过时的依赖项。另外,当我删除包时,我想删除(可能)然后不需要的自动安装的依赖项(即孤儿)。

我发现dnf list installed- 但它不会显示是否明确选择了软件包或由于依赖关系而安装。

我如何在 Fedora 上获取这些信息?

Fedora/dnf 复制软件包选择的方式是什么?

max*_*zig 13

从 Fedora 26 开始, Dnfrepoquery 子命令支持有一个新选项来列出所有用户安装的软件包:

$ dnf repoquery --qf '%{name}' --userinstalled \
 | grep -v -- '-debuginfo$' \
 | grep -v '^\(kernel-modules\|kernel\|kernel-core\|kernel-devel\)$' > pkgs_a.lst
Run Code Online (Sandbox Code Playgroud)

与其他方法相比,它还列出了所有 debuginfo 包。上面示例中的附加 grep 将它们过滤掉。

在主机 B 上安装列表:

$ < pkgs_a.lst xargs dnf -y install
Run Code Online (Sandbox Code Playgroud)

DNF API

使用最新的 Dnf 版本(例如 Fedora >= 23),可以通过 Dnf Python API 查询包数据库以获取用户安装的包名称:

$ python3 -c 'import dnf; b = dnf.Base(); b.fill_sack(); \
  l = sorted(set(x.name for x in b.iter_userinstalled() \
       if not x.name.endswith("-debuginfo") \
          and x.name not in \
             ["kernel-modules", "kernel", "kernel-core", "kernel-devel"] )); \
  print("\n".join(l)) ' > pkgs_a.lst

# dnf install $(cat pkgs_a.lst) # on host_b
Run Code Online (Sandbox Code Playgroud)

默认情况下,dnf install如果一个或多个包不再可用,则中止。或者,可以强制dnf安装所有剩余的:

# dnf install --setopt=strict=0 $(cat pkgs_a.lst) # on host_b
Run Code Online (Sandbox Code Playgroud)

PS:将上面的代码和更多内容放入user-installed.py其中也支持其他发行版。

历史用户安装

在 Fedora 23 及更高版本上,Dnf 提供了

# dnf history userinstalled
Run Code Online (Sandbox Code Playgroud)

命令列出所有用户安装的软件包。截至 2016-11,它的用处是有限的,因为无法控制它的输出并且它打印完全合格的包(即包括版本信息)。

用户安装的限制

请注意,将软件包标记为用户安装的在某些 Fedora 版本上有一些限制,对于 Fedora 23 时代的系统(从 2015-11 年左右),以下问题是相关的):

重新查询

在旧的 Fedora 系统上,Dnf、Dnf APIdnf history userinstalled不可用,可以使用repoquery代替,例如:

$ repoquery --installed \
     --qf '%{n} | %{yumdb_info.reason} | %{yumdb_info.installed_by}' --all \
    | awk -F'|' ' $2 ~ /user/ && ($3 != 4294967295) { print $1 }'  \
    | sort -u > pkgs_a.lst
Run Code Online (Sandbox Code Playgroud)

第二个 awk 条件用于排除安装程序安装的包。安装程序的用户 ID 显然存储为 4294967295 - 或者您可以编写类似($3 == 0 || $3 == your-user-id).

请注意,此命令适用于 Fedora 21 版以上 - 但例如不适用于 23 版,因为该命令repoquery已被替换为dnf repoquery. 并且dnf repoquery不理解%{yumdb_info.reason}标签。


Jam*_*ill 7

最简单的方法,它已经工作了很长时间:

yum-debug-dump => gives file.

yum-debug-restore <file-from-debug-dump>
Run Code Online (Sandbox Code Playgroud)

...它的工作原理很像 get/set selections dpkg 命令,AIUI。另请注意,如果您正在重播历史,您可以使用:

yum history addon-info last saved_tx => gives file
yum load-tx <file-from-addon-info>
Run Code Online (Sandbox Code Playgroud)

...而不必自己解析它。