仅列出rpm包中的文件

仅列出rpm包中的文件

启动rpm -ql <somerpm>会列出 rpm 包中包含的文件和目录。严格来说,我只想列出文件,而不是目录。

是否有任何标志或命令不依赖于rpm -ql <somerpm>单独检查每个输出是否是目录(例如[ -d $line ]在每行的 shell 中执行测试)?

答案1

似乎rpm没有内置选项来抑制文件列表输出中的目录。

但是,您可以使用--queryformat选项(不带-l)来打印每个文件的文件模式和文件名,然后将输出通过管道传输到 例如grep以排除那些模式字段以 开头的条目d

rpm -q --qf '[%{FILEMODES:perms} %{FILENAMES}\n]' some_rpm | grep -v '^d'

这仍然会打印那些实际文件条目的模式字段。为了抑制这种情况,您可以使用稍微复杂的sed程序:

rpm -q --qf '[%{FILEMODES:perms} %{FILENAMES}\n]' some_rpm | sed -nE '/^[^d]/s/.* //p'

默认情况下,这将抑制输出,仅考虑那些执行此操作的行不是从 开始d,并删除第一列。


之前版本的答案

但是,您可以利用详细输出将打印文件的样式列表的事实ls -l,并将输出通过管道传输到 例如,grep以排除权限字段以 开头的那些条目d

rpm -ql -v some_rpm | grep -v '^d' 

请注意,这仍将保留“完整”输出样式。如果要将输出限制为实际文件名,可以将输出通过管道传输到稍微复杂的awk程序,该程序将仅打印最后一列,即实际文件名。我已经包含了一项检查,以查看该文件是否是符号链接,由->倒数第二列标识,在这种情况下,它将打印链接名称而不是链接目标:

rpm -ql -v some_rpm | awk '$1 !~ /^d/ {if ($(NF-1) != "->") {print $NF;} else {print $(NF-2)}}'

然而,这会偶然发现文件名中含有空格,所以这里你需要小心。

答案2

有几个选项可以限制输出:

-c, --configfiles
  List only configuration files (implies -l).

-d, --docfiles
  List only documentation files (implies -l).

但所有文件都没有(并且仅有的文件)从我所看到的。所以,类似于管理员蜜蜂的回答,我建议处理输出,但使用以下--dump选项:

--dump  Dump file information as follows:

   path size mtime md5sum mode owner group isconfig isdoc rdev symlink

This option must be used with at least one of -l, -c, -d.

检查示例包的输出(如bash),md5sum目录和符号链接的 s 均为零,但如果该条目不是符号链接,则最后一列为X。所以:

  • 仅打印目录:

    rpm -q -l --dump package | awk '$4 ~ /^0+$/ && $NF == "X" {print $1}'
    
  • 仅打印符号链接:

    rpm -q -l --dump package | awk '$4 ~ /^0+$/ && $NF != "X" {print $1}'
    
  • 仅打印文件:

    rpm -q -l --dump package | awk '$4 !~ /^0+$/ && $NF == "X" {print $1}'
    

Amazon Linux 2023 Docker 映像的输出示例:

$ rpm -q bash -l --dump | awk '$4 !~ /^0+$/ && $NF == "X" {print $1}' | head # Limiting output for regular files
/etc/skel/.bash_logout
/etc/skel/.bash_profile
/etc/skel/.bashrc
/usr/bin/alias
/usr/bin/bash
/usr/bin/bashbug-64
/usr/bin/bg
/usr/bin/cd
/usr/bin/command
/usr/bin/fc

$ rpm -q bash -l --dump | awk '$4 ~ /^0+$/ && $NF != "X" {print $1}'  # Symlinks
/usr/bin/bashbug
/usr/bin/sh
/usr/lib/.build-id/f2/caf7678bcb7e7d116f91109985f2f0209e714b
/usr/share/man/man1/bashbug-64.1.gz
/usr/share/man/man1/sh.1.gz

$ rpm -q bash -l --dump | awk '$4 ~ /^0+$/ && $NF == "X" {print $1}' # directories
/usr/lib/.build-id
/usr/lib/.build-id/f2
/usr/share/doc/bash
/usr/share/licenses/bash

再看一下,它mode也有效:似乎该模式以04(例如040755) 开头用于目录,以012(例如0120777) 开头用于符号链接,010对于常规文件,因此可以使用它来代替。例如,要打印目录:

rpm -q -l --dump package | awk '$(NF - 6) ~ /^04/ {print $1}'

或者列出文件:

rpm -q -l --dump package | awk '$(NF - 6) ~ /^010/ {print $1}'

答案3

libarchive 所使用的bsdtarbsdcpio许多图形存档提取器支持 RPM 文件,因此您可以使用它bsdtar来将 RPMtar即时转换为格式,并使用star其选项按类型过滤存档成员-find

bsdtar cf - @file.rpm | star tf - -find ! -type d

排除d目录类型的文件或-type f而不是! -type f仅包含常规的文件,不包括所有其他类型的文件,包括目录、符号链接、设备、fifos...

或者,由于 GNUtar将 a 附加/到其列表中的目录末尾,如果您可以保证 RPM 的路径中没有带有换行符的成员:

bsdtar cf - @file.rpm | tar tf - | grep -v '/$'

相关内容