源shell脚本进入ruby脚本中的环境

Cha*_*lie 7 ruby shell environment scripting

如果我正在编写shell脚本并且我想"获取"一些外部(c-)shell脚本来设置我的环境,我可以像这样调用:

source /file/I/want/to/source.csh
Run Code Online (Sandbox Code Playgroud)

我想用ruby脚本替换执行此操作的shell脚本.我可以在ruby脚本中做类似的事情吗?

更新:

刚试用test_script.csh:

#!/bin/csh

setenv HAPPYTIMES True
Run Code Online (Sandbox Code Playgroud)

...和test_script.rb:

#!/usr/bin/env ruby
system "~/test_script.csh"
system "echo $HAPPYTIMES"
Run Code Online (Sandbox Code Playgroud)

可悲的是,到目前为止还没有任何快乐.

小智 6

鉴于以下Ruby

# Read in the bash environment, after an optional command.
#   Returns Array of key/value pairs.
def bash_env(cmd=nil)
  env = `#{cmd + ';' if cmd} printenv`
  env.split(/\n/).map {|l| l.split(/=/)}
end

# Source a given file, and compare environment before and after.
#   Returns Hash of any keys that have changed.
def bash_source(file)
  Hash[ bash_env(". #{File.realpath file}") - bash_env() ]
end

# Find variables changed as a result of sourcing the given file, 
#   and update in ENV.
def source_env_from(file)
  bash_source(file).each {|k,v| ENV[k] = v }
end
Run Code Online (Sandbox Code Playgroud)

和以下test.sh:

#!/usr/bin/env bash
export FOO='bar'
Run Code Online (Sandbox Code Playgroud)

你应该得到:

irb(main):019:0> source_env_from('test.sh')
=> {"FOO"=>"bar"}
irb(main):020:0> ENV['FOO']
=> "bar"
Run Code Online (Sandbox Code Playgroud)

请享用!


ram*_*ion 5

这对您不起作用的原因是 b/c rubysystem在单独的 shell 中运行其命令。因此,当一个系统命令完成时,提供文件的 shell 将关闭,并且在该 shell 中设置的任何环境变量都会被遗忘。

如果您直到运行时才知道源文件的名称,那么Roboprog 的答案是一个很好的方法。但是,如果您提前知道源文件的名称,则可以使用 hashbang 行进行快速破解。

% echo sourcer.rb
#!/usr/bin/env ruby
exec "csh -c 'source #{ARGV[0]} && /usr/bin/env ruby #{ARGV[1]}'"
% echo my-script.rb
#!/usr/bin/env ruby sourcer.rb /path/to/file/I/want/to/source.csh
puts "HAPPYTIMES = #{ENV['HAPPYTIMES']}"
% ./my-script.rb
HAPPYTIMES = True
Run Code Online (Sandbox Code Playgroud)

所有这些只会帮助您在 ruby​​ 脚本中使用设置的环境变量,而不是在您的 shell 中设置它们(因为一旦 ruby​​ 进程完成它们就会被遗忘)。为此,您被source命令困住了。