我正在尝试从我的ruby程序中运行一些第三方bash脚本。
在我运行它们之前,它们需要我来源文件。在命令行上它一切正常但在Ruby中它不起作用。我发现系统命令将打开一个新的子shell进程,任何源代码都将在那里完成,并且无法从运行Ruby脚本的父shell进程中看到。当系统调用结束时,子shell也被杀死。
我如何解决这个问题?
答案 0 :(得分:8)
这样做:
$ source whatever.sh
$ set > variables.txt
然后在Ruby中:
File.readlines("variables.txt").each do |line|
values = line.split("=")
ENV[values[0]] = values[1]
end
运行完之后,您的环境应该不错。
答案 1 :(得分:2)
我不确定我是否理解你的问题。您是否尝试在运行另一个脚本之前获取shell脚本?在这种情况下,答案很简单:
#!/bin/env ruby
system "source <path_to_source_file> && <command>"
如果源文件包含您的命令应该使用的变量,则必须export
它们。也可以使用ENV['<name_of_var>'] = <value>
。
更新:2010年1月26日 - 15:10
您可以使用IO.popen打开一个新shell:
IO.popen("/bin/bash", "w") do |shell|
shell.puts "source <path_to_source_file>"
shell.puts "<command>"
end
答案 2 :(得分:2)
这太可怕了,但是......
env = %x{. /some/shell/script/which/setups/your/env && env}
env.split("\n").each do |line|
key, value = line.split("=", 2)
ENV[key] ||= value unless value.nil? or value.empty?
end
答案 3 :(得分:0)
我之所以这样做,是因为我不想写这个文件或将我的ruby代码与这些东西混淆:
#!/usr/bin/env bash
eval $(echo "$(cat .env) $1" | tr '\n' ' ')
我把它放在〜/ bin / run_with_env.sh然后例如我可以运行:
% run_with_env.sh "rails console"
答案 4 :(得分:0)
修改ENV仅适用于单个线程,而是执行以下操作。 但是我有一个问题如何使用IO.popen的环境合并COPY?不知怎的,它似乎没有用。
用“系统”我可以做到:
# ... create new "path" here
subEnv = Hash.new;
subEnv.merge!(ENV); # copy old environment
subEnv['PATH'] = path; # set new values in copy
system(subEnv, commandLine);