查找包管理器未安装的文件

查找包管理器未安装的文件

我想获得我的 Gentoo Linux 系统中未由包管理器 (Portage) 安装的所有文件的列表。这是因为我想保持系统尽可能干净,删除周围所有无用的文件。

让我告诉你到目前为止我已经尝试过的事情。首先,我生成属于 Portage 跟踪的某个包的所有文件的列表:

equery files "*" | sort | uniq > portage.txt

然后我生成系统上所有文件的列表,除了那些我不关心的文件:

find / \( -path /dev -o -path /proc -o -path /sys -o -path /media \
          -o -path /mnt -o -path /usr/portage -o -path /var/db/pkg \
          -o -path /var/www/localhost/htdocs -o -path /lib64/modules \
          -o -path /usr/src -o -path /var/cache -o -path /home \
          -o -path /root -o -path /run -o -path /var/run -o -path /var/tmp \
          -o -path /var/log -o -path /tmp -o -path /etc/config-archive \
          -o -path /usr/local/portage -o -path /boot \) -prune \
          -o -type f | sort | uniq > all.txt

最后,我得到了 Portage 未跟踪的所有文件的列表:

comm -13 portage.txt all.txt > extra.txt

一些统计数据:

wc -l portage.txt all.txt extra.txt
  127724 portage.txt
   78371 all.txt
    8438 extra.txt

如您所见,我仍然获得了超过八千个额外文件。我想减少这个数字,以便更多地关注真正需要删除的文件。

我注意到在extra.txt少数目录中有数千个文件,例如/usr/lib64/gcc/usr/lib64/python2.7/usr/lib64/python3.2。例如,该/usr/lib64/gcc/x86_64-pc-linux-gnu/4.6.3/crtbegin.o文件不在,portage.txt因为在它的位置上有/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.3/crtbegin.o.在我的系统上/usr/lib有一个符号链接到/usr/lib64.所以看来我需要正确处理符号链接以获得更好的结果。也许通过添加portage.txt它们指向的所有文件。我真的不知道该怎么做。

另外,为什么portage.txt大于all.txt?不应该是相反的,因为 Portage 跟踪的文件是我系统中所有文件的子集?

find最后,我是否忘记了命令中也应排除的任何其他位置?

答案1

您正在寻找的可能是qfile。它是包的一部分app-portage/portage-utils,并提供选项-o--orphans。你可以使用类似的东西

find /usr/bin -type f | xargs -I{} qfile -o {}

获取 中的孤立文件列表/usr/bin

备注:遗憾的是,qfile在当前稳定版本的 portage-utils 中,不支持从 stdin 读取,并且 qfile 手册页中提到的解决方案qfile -o $(find /usr/bin)在查找结果集很大时不起作用,因此我们必须解决它一点点,使用xargs.

顺便说一句,这不是我自己想出来的,而是我在游丝线程,yvasilev 的评论

答案2

portage.txt我设法通过运行以下命令来修复与符号链接相关的问题:

equery files '*' | while read i; do readlink -e "${i}"; done | sort | uniq \
       > portage.txt

这用于放入portage.txt符号链接指向的文件,而不是符号链接本身。这是必需的,因为find创建的命令all.txt不会列出任何符号链接,而只是列出它们指向的文件,因此否则会出现很多误报。这是一个相当慢的命令,因为它运行readlink在数千个文件上,但我找不到更好的解决方案。欢迎任何建议。

我理解的另一件事(这更容易)是为什么portage.txt比 更大all.txt。这主要是因为我/usr/src从命令结果中明确删除了目录及其下面的所有文件find,但equery无论如何都列出了它们。

我做的最后一件事,即使这不是问题,也是忽略 Python 的东西(主要是文件和带有或后缀的__pycache__文件):.pyc.pyo

grep '\(\.cpython-32\)\?\.py[co]$\|/__pycache__' candidates.txt \
     > candidates-bytecode.txt
sed -e 's/\(\.cpython-32\)\?\.py[co]$/.py/' \
    -e 's/\/__pycache__//' \
    candidates-bytecode.txt | sort | uniq \
    > candidates-bytecode-source.txt
comm -23 candidates-bytecode-source.txt portage.txt \
     > orphaned-bytecode.txt

通过这种方式,我可以追踪所有 Python 内容的起源并检查它是否在portage.txt.正如您所看到的,我将相同的正则表达式写了两次,一次用于命令grep,另一次用于sed命令,但也许只需一步即可完成。

答案3

IIRC,gentoo以纯文本形式存储包信息(也许是/var/db/),直接搜索可能会很慢。

最好的方法是为所有包文件创建一个sqlitedatabase(或任何数据库),然后列出系统上的所有文件,在数据库中一一查找它们,如果没有找到,则它不属于portage 。

相关内容