使用 rpm/grep 检查是否安装了多个服务 - 作为一个衬垫?

使用 rpm/grep 检查是否安装了多个服务 - 作为一个衬垫?

以下代码用于检查服务(从变量读取,可以为空或最多 X 个指定服务)是否已安装并采取适当的操作。

... if ! rpm -qa | grep -qw $SERVICE; then ...

我怎样才能实现相同的目标,但允许设置和读取以下格式的变量:

选项 - 一行中的变量以单个空格分隔:示例:SERVICE=httpd mariadb mariadb-server

基本上我想要一个单行检查是否安装了服务(可以是从 0 - 99)。

完整的想法:

SERVICE=mariadb httpd

if [ "`systemctl is-active $SERVICE`" != "active" ]; then
  if ! rpm -qa | grep -qw $SERVICE; then 
    yum -y install $SERVICE;
    echo "$SERVICE has been installed.";
  else systemctl start $SERVICE && echo "$SERVICE started"; \
  fi
fi

答案1

尝试这个:

for f in $SERVICE; do if ! rpm -qa \| grep -qw $f; then ... fi; done

答案2

参考 CentOS 6,服务将匹配下面的文件名之一/etc/rc.d/init.d

出于您的目的,请忽略并非来自 RPM 的偶尔自定义服务脚本,只需执行

for f in $SERVICE; do s=/etc/rc.d/init.d/$f; [ -f "$s" ] && rpm -qf "$s"; done

这将检查服务文件是否存在并打印相应包的名称。如果服务文件丢失,则不会打印任何内容。

在测试语法时,我制作了一个脚本,SERVICE从命令行参数进行设置,例如,

SERVICE="$*"

显示了示例输入/输出:

$ /tmp/foo avahi-daemon blk-availability bluetooth certmonger cgconfig cgred cpusp
eed crond
avahi-0.6.25-15.el6.x86_64
lvm2-2.02.118-3.el6_7.4.x86_64
bluez-4.66-1.el6.x86_64
certmonger-0.77.5-1.el6.x86_64
libcgroup-0.40.rc1-16.el6.x86_64
libcgroup-0.40.rc1-16.el6.x86_64
cpuspeed-1.5-22.el6.x86_64
cronie-1.4.4-15.el6_7.1.x86_64

为此,在您的示例中

if ! rpm -qa | grep -qw $SERVICE; then 

你会把它替换为

if [ -z "$( rpm -qf /etc/rc.d/init.d/$SERVICE 2>/dev/null )" ] ; then

如果服务文件丢失,rpm将向标准错误写入一条错误消息。如果它存在,但不是来自 RPM,rpm则会向标准输出返回一条消息(这是一致的:您不应该安装某些东西来替换自定义脚本)。

对于 CentOS 7,使用systemd,您可以使用相同的想法,但具有不同的目录布局。它将“.service”文件存储在

/usr/lib/systemd/system/

可以测试为

if [ -z "$( rpm -qf /usr/lib/systemd/system/${SERVICE}.service 2>/dev/null )" ] ; then

在我的 CentOS 7 机器上

  • 有 384 个单元文件列出者systemctl list-unit-files
  • 101 在默认配置中被禁用
  • 275 是“.service”文件
  • 其余部分 (109) 的后缀为“.mount”、“.path”、“.slice”、“.socket”、“.target”

假设您检查了与包匹配的服务名称,如下所示:

  • 其中有十几个左右服务名称包含不会在包名称中使用的字符,例如'@''.'。同样,搜索所有服务的列表。
  • 需要一段时间(处理整个列表大约需要 5 分钟),并且无法匹配列表中 220 个内容(成功率为 20%)。
  • 许多匹配都是巧合,发现了多个包(将其视为另一个 70% 的失败)。
  • 总的来说,成功率为 5%。

另一方面,使用该rpm -qf方法处理列表大约需要 30 秒,并且 100% 成功。

答案3

我相信我最初的问题没有提供您所需的详细规格,并且您提供的解决方案可以工作 - 但在我的情况下,它们在某些方面几乎不起作用。

然而,你让我走上了(对我来说)正确的道路,下面的内容满足了我的需要——很确定有更好的方法,但至少它有效,我明白发生了什么:)

感谢您对此的支持。

PACKAGE="mariadb-server httpd"
SERVICE="mariadb httpd"

for f in $PACKAGE
do
  if ! rpm -qa \| grep -qw ${f}
  then
    yum -y install ${f}
  fi
done

for f in $SERVICE
do
  if [ "systemctl is-active ${f}" != "active" ]
  then
    systemctl enable ${f}
    systemctl start ${f}
  fi
done

相关内容