如何通过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
相关产品推荐
相关产品推荐

