web-dev-qa-db-ja.com

Rubyでの環境変数のエクスポート

Rubyスクリプト内から親シェルに環境変数をエクスポートするにはどうすればよいですか?たとえば、read Bashビルトインの単純な実装を実装します。

#!/usr/bin/Ruby

varname = ARGV[0]
ENV[varname] = STDIN.gets  # but have varname exported to the parent process
37
wilhelmtell

簡単な答え:できません。

より長い答え:操作環境がそうするためのフックを提供しない限り、あなたはできません。ほとんどはありません。通常できる最善の方法は、実行したい割り当てを印刷して、親に実行させることです。

Rubyスクリプトが実行されるシェルに環境変数をエクスポートすることはできませんが、ソース可能bashファイルを作成するRubyスクリプトを作成できます。

例えば

% echo set_var.rb
#!/usr/bin/env Ruby
varname = ARGV[0]
puts "#{varname}=#{STDIN.gets.chomp}"
% set_var.rb FOO
1
FOO=1
% set_var.rb BAR > temp.sh ; . temp.sh
2
% echo $BAR
2
%

別の選択肢は、ENV[]=は、Rubyプロセス内から開かれたサブシェルの環境変数を設定します。例:

outer-bash% echo pass_var.rb
#!/usr/bin/env Ruby
varname = ARGV[0]
ENV[varname] = STDIN.gets.chomp
exec '/usr/bin/env bash'
outer-bash% pass_var.rb BAZ
quux
inner-bash% echo $BAZ
quux 

これは、シェルのexecコマンドと組み合わせると非常に強力になる可能性があります。このコマンドは、外側のシェルをRubyプロセスに置き換えるため、内側のシェルを終了すると、外側のシェルも自動的に終了し、「このシェルにその変数を設定したと思った」という混乱を防ぎます)。

# open terminal
% exec pass_var.rb BAZ
3
% echo $BAZ
3
% exit
# terminal closes
36
rampion

私はこれを試してみましたが、見た目は良いです。

cmd = "echo \"FOO is \\\"$FOO\\\"\"";                                
system(cmd);

# Run some Ruby code (same program) in the child process
fork do
    puts "In child process. parent pid is #$$"
    ENV['FOO']='foo in sub process';
    system(cmd);
    exit 99
end
child_pid = Process.wait
puts "Child (pid #{child_pid}) terminated with status #{$?.exitstatus}"

system(cmd);

これはうまくいくようです-少なくともMacOSXでは

私は得る

FOO is ""
In child process. parent pid is 1388
FOO is "foo in sub process"
Child (pid 1388) terminated with status 99
FOO is ""

それは以前の状態を自動的に復元するのがいいようです

わかりました-これで2つのサブプロセスが生成されないため、別の方法を試しました

Use Process.spawn(env,command)

pid = Process.spawn({ 'FOO'=>'foo in spawned process'}, cmd );
pid = Process.wait();  

これはCシステムコールのように機能し、パイプやその他すべてのものも指定できます。

8
peterk

In Ruby=標準エクスポートコードの出力:

puts "export MYVAR=value"

シェルバックティックを使用して、シェルコマンドで実行します。

$ `./myscript.rb` 

これは、スクリプトの出力を取得して実行し、bashやzshなどの最新のシェルで動作します

0
Seeder