variable - set env var ruby




Exportation d'une variable d'environnement en Ruby (3)

Comment exporter une variable d'environnement depuis un script Ruby vers le shell parent? Par exemple, implémenter une implémentation naïve de la commande intégrée Bash en lecture:

#!/usr/bin/ruby

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

Je viens d'essayer cela et ça a l'air bien.

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);

Cela semble bien fonctionner - du moins sur MacOSX

Je reçois

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

Semble gentil, il restaure automatiquement l'état antérieur

Ok - maintenant essayé un autre, car cela ne génère pas 2 sous-processus

Use Process.spawn(env,command)

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

Cela agit comme l’appel du système C et vous permet de spécifier des tuyaux et tous ces autres éléments.


Qu'en est-il de l'impression en ruby ​​du code d'exportation standard:

puts "export MYVAR=value"

puis en utilisant shell backtick pour le faire exécuter aux commandes shell:

$ `./myscript.rb` 

cela prendra la sortie du script et l'exécutera, fonctionne dans les shells modernes comme bash et zsh


Vous ne pouvez pas exporter de variables d’environnement vers le shell dans lequel le script ruby ​​s’exécute, mais vous pouvez écrire un script ruby ​​qui crée un fichier bash source.

Par exemple

% 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
%

Une autre alternative est d'utiliser ENV[]= définir les variables d'environnement des sous-réservoirs ouverts à partir du processus ruby. Par exemple:

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 

Cela peut être assez puissant si vous le combinez avec la commande exec du shell, qui remplacera la coque externe par le processus ruby ​​(de sorte que lorsque vous quittez la coque interne, la coque externe se ferme automatiquement, empêchant ainsi toute "Je pensais J'ai mis cette variable dans cette coquille "confusion".

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




environment-variables