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


16

我有一个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

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

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

我已经找到了dnf list installed-但是它不会显示是否由于依赖而明确选择或安装了软件包。

我如何在Fedora上获得该信息?

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

Answers:


12

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

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

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

要将列表安装在主机B上:

$ < pkgs_a.lst xargs dnf -y install

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

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

# dnf install --setopt=strict=0 $(cat pkgs_a.lst) # on host_b

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

用户安装的历史记录

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

# dnf history userinstalled

列出所有用户安装的软件包的命令。从2016-11开始,它的用途受到限制,因为无法控制其输出,并且它会打印完全合格的软件包(即,包括版本信息)。

用户安装的限制

请注意,将软件包标记为用户安装在某些Fedora版本上有一些限制,对于Fedora 23-ish时代的系统(大约在2015-11年发行),存在以下问题):

回购查询

在Dnf,Dnf API和Dnf dnf history userinstalled不可用的较旧的Fedora系统上,可以改用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

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

请注意,此命令在Fedora发行版21之前repoquery可用-但在23发行版上无效,因为该命令已被替换dnf repoquery。并且dnf repoquery不了解%{yumdb_info.reason}标签。


我不确定这种方法是否能解决所有问题,我在运行时在系统上注意到了这些问题repoquery ...:“安装的pkg的yumdb querytag'原因'无效:HandBrake-cli-0.9.5-1.fc14.x86_64”
slm

@ slm,hm,从哪个仓库安装了手刹?也许存储库设置与此有关?
maxschlepzig

我认为这可能是我使用安装的独立RPM yum localinstall ...。不过,我有相当数量的包裹落入该营地。
slm

repoquery --installed --qf '%{n} - %{yumdb_info.reason}' --all 2>&1|grep -v "user$"|grep -v "dep$" |wc -l返回了90个包裹。
slm

6

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

yum-debug-dump => gives file.

yum-debug-restore <file-from-debug-dump>

...的工作方式与获取/设置选择dpkg命令AIUI非常相似。另请注意,如果要重播历史记录,则可以使用:

yum history addon-info last saved_tx => gives file
yum load-tx <file-from-addon-info>

...而不是必须自己解析。


3

灵感来自SLM答案我已经想出了以下yum history基础的解决方案:

获取有关所有yum安装事务(即无升级)的所有详细历史记录,但不包括作为初始安装程序操作(我系统上的事务1和2,归因于用户“系统”)的一部分执行的事务:

$ yum history list all | awk -F'|' \
                            '$4 ~ /Install/ && $2 !~ /System/ {print $1}' \
    | xargs yum history info > yum_history

过滤明确安装的软件包并切断版本前缀。

$ < yum_history grep '[^-]\<Install\>' | \
  awk '{ print $2 }' \
  | sed 's/\(-[0-9]\+:\|-[0-9]\+\.[0-9]\|-[0-9]\+-\|-[0-9]\+git\).\+\(\.fc1[1-7]\.\|\.noarch\).*$//' \
  | sort > hist_pkg_list

需要丑陋的正则表达式,以便匹配各种版本的后缀。

结果在我的系统上看起来还不错。

repoquery ansatz的比较(在我的系统上):

方法#包
―――――――――――――――――――――――――――
回购查询569
repoquery-2nd 216
百胜历史214

(我通过排序-u用管道传输了repoquery结果)

为什么会有差异?因为repoquery包含事务1和2中的所有软件包,即Fedora安装程序安装的所有软件包。这解释了为什么repoquery包含提到的软件包xorg-x11-drv-mga和friends。

比较repoquery-2nd和yum-history可以看出repoquery-2nd更加准确-它不包括一些已经删除的软件包。另外,它似乎还包含一些来自“ yum update”操作的软件包(在我的系统上为2个)。

警告

上面的基于历史记录的方法仅列出了系统整个生命周期中所有明确安装的软件包。它不会平衡在以后的事务中删除的那些软件包。因此,该方法需要对结果进行一些手动调整,并且只能在不可用的系统上repoquery使用。


充分利用我们两个答案的好方法!如果可以的话,我会给您提供+1以上的收益+各种方法的比较。
slm

2

我有一个较旧的Fedora版本(14),所以我的百胜版本包含功能较少的yum,但您可能想看看该yum history功能。我相信您可以从该命令获得所需的信息。

历史清单

$ sudo yum history list
Loaded plugins: langpacks, presto, refresh-packagekit
Adding en_US to language list
ID     | Login user             | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
   862 | System <unset>         | 2013-07-12 18:00 | Install        |    1   
   861 | System <unset>         | 2013-07-09 03:11 | Install        |    1   
   860 | System <unset>         | 2013-07-01 13:40 | Install        |    1   
   859 | System <unset>         | 2013-06-29 22:07 | Install        |    1   
   858 | System <unset>         | 2013-06-25 22:33 | Install        |    1 P<
   857 | System <unset>         | 2013-06-23 22:28 | Update         |    1 >E
   856 | System <unset>         | 2013-06-23 21:33 | Install        |    1   
   ...

您可以将数字列表传递给yum history list

$ sudo yum history list `seq 1 10`
Loaded plugins: langpacks, presto, refresh-packagekit
Adding en_US to language list
ID     | Login user             | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
    10 | Sam M. (local) <saml>  | 2010-12-18 23:23 | Install        |    2   
     9 | Sam M. (local) <saml>  | 2010-12-18 23:15 | Install        |   38   
     8 | Sam M. (local) <saml>  | 2010-12-18 23:12 | Install        |    1   
     7 | Sam M. (local) <saml>  | 2010-12-18 23:09 | Install        |    1  <
     6 | Sam M. (local) <saml>  | 2010-12-18 22:37 | Install        |    1 > 
     5 | Sam M. (local) <saml>  | 2010-12-18 21:57 | Install        |    1   
     4 | System <unset>         | 2010-12-18 21:21 | Install        |    5   
     3 | System <unset>         | 2010-12-18 21:18 | Install        |    4   
     2 | System <unset>         | 2010-12-18 21:10 | Install        |    3   
     1 | System <unset>         | 2010-12-18 19:14 | Install        | 1189

历史信息

下面将向您展示在第一个yum事务中安装了什么:

$ sudo yum history info 1 | less
Loaded plugins: langpacks, presto, refresh-packagekit
Adding en_US to language list
Transaction ID : 1
Begin time     : Sat Dec 18 19:14:05 2010
Begin rpmdb    : 0:da39a3ee5e6b4b0d3255bfef95601890afd80709
End time       :            19:42:43 2010 (1718 seconds)
End rpmdb      : 1189:8c21e9e377c3ebdee936916208f74232d5d6235f
User           : System <unset>
Return-Code    : Success
Transaction performed with:
Packages Altered:
    Dep-Install ConsoleKit-0.4.2-3.fc14.x86_64
    Dep-Install ConsoleKit-libs-0.4.2-3.fc14.x86_64
    Dep-Install ConsoleKit-x11-0.4.2-3.fc14.x86_64
    Dep-Install GConf2-2.31.91-1.fc14.x86_64
    Dep-Install GConf2-gtk-2.31.91-1.fc14.x86_64
    Dep-Install ModemManager-0.4-4.git20100720.fc14.x86_64
    Install     NetworkManager-1:0.8.1-10.git20100831.fc14.x86_64
    Dep-Install NetworkManager-glib-1:0.8.1-10.git20100831.fc14.x86_64
    Install     NetworkManager-gnome-1:0.8.1-10.git20100831.fc14.x86_64
    Install     NetworkManager-openconnect-0.8.1-1.fc14.x86_64

请注意yum如何报告软件包是显式安装还是因为依赖项需要安装。您可以解析此信息,并获取已明确安装的软件包的列表。


我已经根据您的yum history想法添加了一个答案,并且还将结果与repoquery基于该方法的结果进行了比较。作为副作用,我扩展了我的repoquery答案。
maxschlepzig 2013年

1
dnf repoquery --qf "%{name}" --userinstalled > userinstalled.txt

1
当您查看此处的其他5个答案时,您发现答案有什么不同?绝对没有任何关于为什么如何使您的答案更好的解释。如果您能提供一些涵盖这些内容的答案的描述,那将是很好的。
斯蒂芬·劳赫

@StephenRauch,此命令未包含在其他答案中,因为它是dnf的新增功能。该--userinstalled开关刚在5月添加到dnf中。我已经测试过了,它给出了准确的结果。对不是真正由用户安装的kernel / kernel-core / kernel-modules软件包进行模块化。它还包含所有*-debuginfo软件包-但如有必要,可以很容易地将它们过滤掉。
maxschlepzig

@maxschlepzig,感谢您的反馈,但这实际上是一个反问,试图教育/提示回答者在答案中进行解释。
斯蒂芬·劳奇

@StephenRauch,很公平,一定要进行适当的编辑,并允许我将其标记为已接受的答案。
maxschlepzig

0

要列出已安装的软件包,请尝试以下一种方法

alias yum-userinstall="yumdb search command_line install* | grep command_line\ = | sort | uniq | sed -r -e 's/command_line = (.*)/yum \1/g'"

结果:

# yum-userinstall
     yum install bind-utils
     yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
     yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
     yum install lsof
     yum install nano
     yum install nfs-utils libnfsidmap
     yum install nmap-ncat
     yum install openscap-scanner
     yum install open-vm-tools

PS1:不显示依赖项

PS2:按字母顺序排序

PS3:如果以后再删除软件包,它不会显示


-1

我做了什么(忘记细节了,我是个懒惰的流氓,所以...

获取所有已安装的软件包: rpm -qa > file

用于sed(1)摆脱版本号等(如果需要,保留体系结构)。这需要几次迭代才能正确完成,您想用任何内容代替最后一个-[0-9.]-[0-9].fc23或类似内容,但也有一些有趣的版本“数字”。

正常安装后,执行yum -y install $(< file)(或dnf,根据需要)。

您将获得一些不再存在,名称更改或被其他软件包取代的软件包的影响。


好的,但这会将所有先前安装的软件包标记为目标主机上的用户安装。即使它们最初只是作为依赖项安装。
maxschlepzig
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.