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

如何通过Chef recipe读取Shell脚本输出并设置为环境变量?

你现在的代码无法生效是因为Chef的执行逻辑存在编译、执行两个阶段的时序差:environment属性属于Ruby层代码,会在编译阶段就完成解析取值,而bash资源内的Shell脚本要等到后续的执行阶段才会运行,你在Shell里定义的$password变量是执行阶段才生成的,编译阶段的Ruby代码根本读取不到这个值。

下面是对应不同需求的正确实现:

场景1:密码仅在当前bash资源的脚本内使用

这种情况不需要额外配置environment,直接在Shell脚本内定义变量后使用即可:

bash 'set_password' do
  code <<-EOH
          password=$(sh /opt/get_password.sh root)
          # 后续直接在当前脚本内使用$password即可
          echo $password
      EOH
  guard_interpreter :bash
end unless node.attribute?('ec2')

场景2:密码需要作为环境变量给其他Chef资源共用

这种情况直接在Ruby层执行脚本获取返回值,再赋值给环境变量即可:

# 先在Ruby层执行脚本获取密码,去掉末尾的换行符
root_password = `sh /opt/get_password.sh root`.chomp
# 赋值给Chef全局环境变量,后续所有资源都能继承该变量
ENV['password'] = root_password

# 如果只需要给特定资源传递变量,也可以直接给environment传取值结果
bash 'other_task_need_password' do
  code <<-EOH
    echo $password
  EOH
  environment ({ 'password' => root_password })
end

如果你的/opt/get_password.sh脚本本身是Chef执行过程中才生成的,需要延迟到执行阶段再取密码,可以用ruby_block实现:

ruby_block 'fetch_root_password' do
  block do
    root_password = `sh /opt/get_password.sh root`.chomp
    ENV['password'] = root_password
  end
  action :run
end unless node.attribute?('ec2')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:06:03