Rubyスクリプト内から親シェルに環境変数をエクスポートするにはどうすればよいですか?たとえば、read
Bashビルトインの単純な実装を実装します。
#!/usr/bin/Ruby
varname = ARGV[0]
ENV[varname] = STDIN.gets # but have varname exported to the parent process
簡単な答え:できません。
より長い答え:操作環境がそうするためのフックを提供しない限り、あなたはできません。ほとんどはありません。通常できる最善の方法は、実行したい割り当てを印刷して、親に実行させることです。
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
私はこれを試してみましたが、見た目は良いです。
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システムコールのように機能し、パイプやその他すべてのものも指定できます。
In Ruby=標準エクスポートコードの出力:
puts "export MYVAR=value"
シェルバックティックを使用して、シェルコマンドで実行します。
$ `./myscript.rb`
これは、スクリプトの出力を取得して実行し、bashやzshなどの最新のシェルで動作します