启动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 所使用的bsdtar
和bsdcpio
许多图形存档提取器支持 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 '/$'