You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chef中script资源执行无效但execute正常的问题排查求助

问题分析与解决方案:Chef script资源卸载RPM包无效,execute资源正常

问题重现

最初使用script资源编写卸载TrendMicro相关RPM包的Recipe:

script 'uninstall trendmicro package' do
  interpreter 'bash'
  user 'root'
  code <<-BASH
    rpm -qa|grep "ds_agent\|trend"|xargs -I{} rpm -e {}
  BASH
  only_if 'rpm -q ds_agent'
end

执行chef-client -z -o"recipe[ccloud_av_trendmicro::uninstall_tm]"后,日志显示script已执行,但目标RPM包仍存在:

vsa10121641:/tmp/cookbooks # chef-client -z -o "recipe[ccloud_av_trendmicro::uninstall_tm]"
[2022-07-27T08:27:32+00:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 12.19.36
[2022-07-27T08:27:33+00:00] WARN: Run List override has been provided.
[2022-07-27T08:27:33+00:00] WARN: Original Run List: []
[2022-07-27T08:27:33+00:00] WARN: Overridden Run List: [recipe[ccloud_av_trendmicro::uninstall_tm]]
resolving cookbooks for run list: ["ccloud_av_trendmicro::uninstall_tm"]
Synchronizing Cookbooks:
  - ccloud_av_trendmicro (0.0.10)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: ccloud_av_trendmicro::uninstall_tm
  * script[uninstall trendmicro package] action run
    - execute "bash"  "/tmp/chef-script20220727-20794-ewbo7s"
[2022-07-27T08:27:34+00:00] WARN: Skipping final node save because override_runlist was given

Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 02 seconds
vsa10121641:/tmp/cookbooks # rpm -qa|grep "ds_agent\|trend"
trendmicro-updater-1.4268-1.2.SAP.noarch
ds_agent-9.6.2-8140.x86_64
byd-trendmicro-check-1.4859-1.2.SAP.noarch

将资源替换为execute后,卸载成功:

execute 'uninstall trendmicro package' do
  command 'rpm -qa|grep "ds_agent\|trend"|xargs -I{} rpm -e {}'
  only_if 'rpm -q ds_agent'
end

执行后目标包被完全清除:

vsa10121641:/tmp/cookbooks # chef-client -z -o "recipe[ccloud_av_trendmicro::uninstall_tm]"
[2022-07-27T08:32:50+00:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 12.19.36
[2022-07-27T08:32:52+00:00] WARN: Run List override has been provided.
[2022-07-27T08:32:52+00:00] WARN: Original Run List: []
[2022-07-27T08:32:52+00:00] WARN: Overridden Run List: [recipe[ccloud_av_trendmicro::uninstall_tm]]
resolving cookbooks for run list: ["ccloud_av_trendmicro::uninstall_tm"]
Synchronizing Cookbooks:
  - ccloud_av_trendmicro (0.0.10)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: ccloud_av_trendmicro::uninstall_tm
  * execute[uninstall trendmicro package] action run
    - execute rpm -qa|grep "ds_agent\|trend"|xargs -I{} rpm -e {}
[2022-07-27T08:32:53+00:00] WARN: Skipping final node save because override_runlist was given

Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 02 seconds
vsa10121641:/tmp/cookbooks # rpm -qa|grep "ds_agent\|trend"

原因分析

  1. 执行环境差异:
    • script资源会把代码写入临时脚本文件再执行,而execute资源直接在当前shell环境运行命令。当用xargs结合rpm -e时,临时脚本的环境可能缺失关键变量(比如PATH),导致rpm命令执行异常但无明显报错。
    • 即便设置了user 'root',临时脚本的执行权限、上下文和execute直接以root身份运行仍有细微差别,部分RPM包卸载需要特定环境上下文才能完成。
  2. 错误捕获逻辑不同:
    • script资源默认不会因脚本内的命令失败终止执行(除非显式设置returns参数),如果某个rpm -e失败(比如依赖问题),后续命令可能中断但日志无提示;而execute会默认捕获退出码,执行失败会在日志中体现。

解决方案

方案1:修复script资源执行问题

如果坚持用script资源,可做以下调整:

  • 显式指定rpm绝对路径,避免PATH缺失导致命令找不到:
script 'uninstall trendmicro package' do
  interpreter 'bash'
  user 'root'
  code <<-BASH
    /usr/bin/rpm -qa|grep "ds_agent\|trend"|xargs -I{} /usr/bin/rpm -e {}
  BASH
  only_if '/usr/bin/rpm -q ds_agent'
end
  • 添加日志和错误捕获,方便排查:
script 'uninstall trendmicro package' do
  interpreter 'bash'
  user 'root'
  code <<-BASH
    set -euo pipefail
    echo "Starting RPM uninstall..." >> /tmp/tm_uninstall.log
    PACKAGES=$(/usr/bin/rpm -qa|grep "ds_agent\|trend")
    echo "Found packages: $PACKAGES" >> /tmp/tm_uninstall.log
    for pkg in $PACKAGES; do
      echo "Uninstalling $pkg..." >> /tmp/tm_uninstall.log
      /usr/bin/rpm -e "$pkg" >> /tmp/tm_uninstall.log 2>&1
      if [ $? -ne 0 ]; then
        echo "Failed to uninstall $pkg" >> /tmp/tm_uninstall.log
      fi
    done
  BASH
  only_if '/usr/bin/rpm -q ds_agent'
end

方案2:使用execute资源(推荐)

execute资源更适合单条或简单管道命令,执行上下文更直接,避免临时脚本的环境问题,正如测试结果,直接使用即可正常卸载。

更规范的Chef做法是用rpm_package资源,符合Chef资源模型,更好处理依赖和状态跟踪:

# 获取所有需要卸载的包
packages = shell_out!('/usr/bin/rpm -qa | grep "ds_agent\|trend"').stdout.split

packages.each do |pkg|
  rpm_package pkg do
    action :remove
  end
end

内容的提问来源于stack exchange,提问作者EisenWang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 04:48:18