bash_profile is not taking effect with chef-run

2019-02-27 19:15发布

问题:

If I run the below recipe with chef, entries are getting added in ~/.bash_profile, but when I do echo $PATH or echo $JAVA_HOME, the command line returns blank values. What's going on there?

ruby_block  "set-env-java-home" do
  block do
    ENV["JAVA_HOME"] = node['java']['path']
    ENV['PATH'] = "#{ENV['PATH']}:#{node['java']['path']}/bin"
  end
  not_if { $JAVA_HOME == "#{ENV['JAVA_HOME']}" && $PATH = "#{ENV['PATH']}:#{node['java']['path']}/bin" }
end

bash 'set-env-bashrc' do
  code <<-EOH
    echo -e "export JAVA_HOME=$JAVA_HOME" >> ~/.bash_profile
    echo -e "export PATH=$PATH" >> ~/.bash_profile
    source ~/.bash_profile
  EOH
end

回答1:

There are a few things here:

Your not_if is wrong

not_if { $JAVA_HOME == "#{ENV['JAVA_HOME']}" && $PATH = "#{ENV['PATH']}:#{node['java']['path']}/bin" }

You are confusing Ruby and bash here. IN Ruby $JAVA_HOME refers to a global constant. It's unclear to me what your not_if guard is trying to accomplish, but using it as-is is certainly not correct.

Using bash instead of primitive resources

You are using Bash to echo content into a file. This is a perfect job for the file or template resources. The will be idempotent and handle notifications properly:

file '~/.bash_profile` do
  content <<-EOH
    export JAVA_HOME=$JAVAHOME
    export PATH=$PATH
  EOH
end

However, it is worth noting that the script as you have it does nothing. You are setting the values of JAVA_HOME and PATH to themselves. It is likely that you want to use #{ENV['JAVA_HOME']} instead.

Bash is a subshell resource

When you use the bash (or any execute resource), you are executing in a subshell, so things like source or export are not persisted to the parent process.