在运行列表中的Chef配方执行之间保持$ PATH变量

时间:2016-11-16 16:15:50

标签: linux path environment-variables chef chef-recipe

我们为一个节点设置了一个Chef运行列表,比如说,配方A,然后是配方B. 在配方A中,我们执行一个启动script.sh的命令资源,该命令资源使用自定义路径导出目标机器上的$ PATH变量。

接下来,当执行配方B时,它会查找要启动的可执行文件,我们希望它可以执行它查看$ PATH中包含的路径。不幸的是,配方B中的$ PATH变量丢失了配方A中的修改。

上下文是:在一台机器上,我们在特定路径中有一个JVM(不在$ PATH中)。使用配方A,我们启动一个script.sh,将JVM bin路径导出到$ PATH。然后在配方B中我们使用java可执行文件(比方说jar),所以我们希望它正在执行查看我们之前在$ PATH中导出的路径。但它不起作用。

我们希望JVM路径暂时设置为$ PATH,只是为了让配方B执行。我想我们不能使用任何Chef环境变量来实现这一点,因为在分布式场景中,JVM路径可能因机器而异。

非常感谢。

更新:

食谱A

mydir = "/path/to/jvm"
script_name = "script.sh"
sh = File.join(mydir,script_name).gsub("/","\/")
script_str = ". " + sh

# Launch script.sh in order to export Java to PATH
execute "ExecuteScript" do
  command script_str
  user "myuser"
  group "mygroup"
  only_if {File.exists?(File.join(mydir,script_name))}
end

不幸的是我无法发布食谱B,但请记住它不可编辑,它只是执行“java”或“jar”(在$ PATH中查找它们)。

更新2

我在食谱A中解决了以下问题:

javapath = "/path/to/jvm/bin"
ENV['PATH'] = "#{ENV['PATH']}:" + javapath

通过这种方式,我在Ruby执行期间设置了环境变量$ PATH。这使得配方B能够看到该变量,因此执行所需的bin(在我的情况下是jar)。我不知道这是否是一个优雅的解决方案,但它对我有用。

2 个答案:

答案 0 :(得分:0)

  

执行一个启动script.sh的命令资源,然后导出   带有自定义路径的目标计算机上的$ PATH变量。

此导出仅在execute资源中可用,因此对于您的脚本及其调用的任何内容,一旦资源结束,它就会被丢弃。

你的描述听起来好像你一开始做错了,但没有更多的细节,很难为你的用例提供正确的建议。

答案 1 :(得分:0)

当进程分叉时,环境变量从父级继承到子级,但它们不能从子级转换为父级。当Chef运行您的外部命令时,任何env var更改都将限定为该进程。您可以使用script资源在单个进程中运行更长的shell代码块,以便它可以共享env vars。