首页 > 解决方案 > 如何从 yum 生成可用更新列表并导出到 CSV,包括每个包的当前和更新版本?

问题描述

我在 Centos 7 机器上运行以下脚本。这个想法是列出当前可更新的软件包,以及当前版本和新版本。完成此操作后,我会将结果发送到 .csv 文件以导入 excel。

这是我正在使用的 bash 脚本:

#! /usr/bin/bash

echo \"timestamp\",\"package name\",\"current version\",\"update version\"
yum -q check-update| while read i
do
    i=$(echo $i) #this strips off yum's irritating use of whitespace
    if [ "${i}x" != "x" ]
    then
        TIMESTAMP=$( date +%D" "%r )
        UVERSION=${i#*\ }
        UVERSION=${UVERSION%\ *}
        PNAME=${i%%\ *}
        PNAME=${PNAME%.*}
        echo \"$TIMESTAMP\",$(rpm -q "${PNAME}" --qf '"%{NAME}","%{VERSION}","')${UVERSION}\"
    fi
done

结果如下所示:

"时间戳","包名称","当前版本","更新版本"
"06/20/18 02:19:37 PM","cloudbackup-updater","1.5.3","1.5.16-1 "
"06/20/18 02:19:37 PM","dhclient","4.1.1","12:4.1.1-53.P1.el6.centos.4"
"06/20/18 02: 19:37 PM","dhcp-common","4.1.1","12:4.1.1-53.P1.el6.centos.4"
"06/20/18 02:19:37 PM","内核","2.6.32",""内核","2.6.32",""内核","2.6.32",""内核","2.6.32",""内核","2.6. 32","2.6.32-696.30.1.el6"
"06/20/18 02:19:37 PM","内核固件","2.6.32","2.6.32-696.30.1.el6"
"06/20/18 02:19:37 PM","内核头文件","2.6.32","2.6.32-696.30.1.el6 "

注意第 5 行是重复信息。我认为这是因为脚本在执行 RPM 查询时查询的是包“kernel”而不是全名“kernel.x86_64”。

如果我跑

yum check-update

以下软件包可用于更新:

cloudbackup-updater.noarch
dhclient.x86_64
dhcp-common.x86_64
kernel.x86_64
kernel-firmware.noarch
kernel-headers.x86_64

我的脚本有什么问题,导致它只匹配每个包名称的第一部分而不是全名?

标签: linuxbashcentos7rpm

解决方案


问题是PNAME任务

PNAME=${PNAME%.*}

这是我用来从文件名中删除扩展名的东西。您正在删除句号右侧的所有内容(包括)。据我所知,真的不需要这条线。引用变量赋值也是一个好主意。所以是这样的:

TIMESTAMP="$( date +%D" "%r )"
UVERSION="${i#*\ }"
UVERSION="${UVERSION%\ *}"
PNAME="${i%%\ *}"
#PNAME="${PNAME%.*}"

$PNAME这些作业的输出:

cloudbackup-updater.noarch
dhclient.x86_64
dhcp-common.x86_64
kernel.x86_64
kernel-firmware.noarch
kernel-headers.x86_64

编辑 我认为您的 while 循环错误地解析了 yum 的输出。尝试将该行更改为:

yum -q check-update | tr -s " " | while read PNAME UVERSION extra

这应该可以处理 yum 的空间问题,以便您可以删除i=$(echo $i). 此外,这会将各个值直接读入变量中。然后,由于$i不再存在,您可以更改if [ "${i}x" != "x" ]if [ "${PNAME}x" != "x" ](这实际上是检查空白的一种非常聪明的方法)。所以最终的脚本应该是这样的:

echo \"timestamp\",\"package name\",\"current version\",\"update version\"
yum -q check-update | tr -s " " | while read PNAME UVERSION extra
do
    if [ "${PNAME}x" != "x" ]; then
        TIMESTAMP=$( date +%D" "%r )
        echo \"$TIMESTAMP\",$(rpm -q "${PNAME}" --qf '"%{NAME}","%{VERSION}","')${UVERSION}\"
    fi
done

推荐阅读