求助:Bash脚本中用if+grep检查RPM包指定版本的问题
问题分析与修复方案
你的脚本存在两个核心问题:
命令执行上下文错误:
$(rpm -qa | grep "service-7.0.0-1.x86_64")会被本地Shell解析执行,而非在远程服务器上运行。这导致你用本地的RPM包检查结果判断远程服务器状态,完全不符合预期。条件判断逻辑低效且易出错:通过
[ ! $(...) ]依赖命令输出是否为空做判断,既冗余又容易触发边界问题。实际上grep本身的退出状态码就是最佳判断依据——匹配成功返回0,失败返回非0,这才是Shell条件判断的正确姿势。
修复后的脚本(推荐版本)
#!/bin/bash server_host=(server1 server2) for my_hosts in "${server_host[@]}" do ssh -q -o "StrictHostKeyChecking no" root@${my_hosts} <<EOF if rpm -qa | grep -q "service-7.0.0-1.x86_64" then echo "------------------------------------------------" echo "${my_hosts}" echo "------------------------------------------------" echo "package installed with correct version" else echo "------------------------------------------------" echo "${my_hosts}" echo "------------------------------------------------" echo "package installed with incorrect version" fi EOF done
关键修改说明
- 修正命令执行上下文:将
$(rpm -qa | grep ...)改为rpm -qa | grep -q ...,同时确保远程执行逻辑正确——这里保留<<EOF让${my_hosts}被本地Shell替换(用于显示服务器名称),而rpm和grep命令则在远程服务器运行。 - 使用
grep -q简化判断:-q参数让grep静默运行,仅返回退出状态码,避免多余输出干扰脚本逻辑,同时直接用命令退出状态作为if的判断条件,符合Shell脚本最佳实践。
替代修复方案(兼容原逻辑写法)
如果你想保留原有的[ ! ... ]判断形式,只需转义本地解析的$符号,让命令在远程执行:
#!/bin/bash server_host=(server1 server2) for my_hosts in "${server_host[@]}" do ssh -q -o "StrictHostKeyChecking no" root@${my_hosts} <<EOF if [ ! \$(rpm -qa | grep "service-7.0.0-1.x86_64") ] then echo "------------------------------------------------" echo "${my_hosts}" echo "------------------------------------------------" echo "package installed with incorrect version" else echo "------------------------------------------------" echo "${my_hosts}" echo "------------------------------------------------" echo "package installed with correct version" fi EOF done
此方案仅在$()前添加反斜杠\,阻止本地Shell解析该命令替换,确保其在远程服务器执行。
内容的提问来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

