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

Chef不同资源块间传值问题:Redis端口检测后启动逻辑运行报错咨询

问题根因

  • 你在第一个bash资源的Shell脚本中定义的portval_#{port}变量仅存在于当前bash资源运行的独立子Shell进程中,资源执行完成后子Shell销毁,变量直接失效,无法传递给后续资源使用
  • 第二个bash资源的only_if "portval_#{port}"写法会被Chef解析为「执行名为portval_54321的系统命令,根据返回值判断是否执行当前资源」,系统中不存在这个命令,自然会抛出No such file or directory的错误

正确实现方式

你完全不需要单独定义检查用的bash资源,直接把进程检查逻辑放到启动资源的守卫语句中即可,优化后代码如下:

ports.each do |port|
  bash "Starting_redis_after_crash_for_port - #{port}" do
    # 仅当对应端口的redis进程不存在时才执行启动逻辑
    only_if <<-EOH
      pidval=$(ps -ef | grep /opt/redis/src/redis-server | grep ":#{port}" | grep -vc grep)
      [ $pidval -eq 0 ]
    EOH
    code <<-EOH
      rm -f #{port}.pid
      sudo service redis@#{port} start
    EOH
  end
end

如果确实需要在多个资源之间共享运行状态,也可以用Chef提供的临时存储node.run_state实现值传递,示例逻辑如下:

ports.each do |port|
  ruby_block "Check_port_running_#{port}" do
    block do
      pidval = shell_out("ps -ef | grep /opt/redis/src/redis-server | grep :#{port} | grep -vc grep").stdout.to_i
      node.run_state["redis_port_#{port}_alive"] = pidval > 0
    end
  end

  bash "Starting_redis_after_crash_for_port - #{port}" do
    only_if { node.run_state["redis_port_#{port}_alive"] == false }
    code <<-EOH
      rm -f #{port}.pid
      sudo service redis@#{port} start
    EOH
  end
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:09:00