Si j'écris un script shell et je veux "sourire" des scripts externes (c-) shell pour configurer mon environnement, je peux simplement faire des appels comme celui-ci:
#!/usr/bin/env ruby system "~/test_script.csh" system "echo $HAPPYTIMES"
6 Réponses :
system 'source /file/I/want/to/source.sh' Not sure that this will do what you want though. It will execute the source command in a subshell. Try it and see it it does what you're after.
J'ai essayé ceci et il ne semble pas faire ce que je suis après. J'essaie d'obtenir les variables d'environnement définies par le script shell dans l'environnement, le script Ruby est en cours d'exécution.
Les changements d'environnement dans un processus d'enfant n'affectent pas le parent
Je pensais que cela pourrait être le cas. Désolée de vous avoir fait perdre votre temps.
Vous allez devoir écrire une fonction pour exécuter quelque chose comme ce qui suit et capturer la sortie ("Backtick" opération): boucle sur chaque ligne, correspond à quelque chose comme p> puis utilisez la première capture de correspondance en tant que nom var, et la deuxième capture en tant que valeur var. p> (oui, je suis couvert Le fait que je connaisse Perl bien mieux que de rubis, mais l'approche serait la même) p> p>
En fait, ce que j'ai capturé toutes les variables d'environnement après avoir exécuté le script. IFF Les assignations dans le "script" n'ont aucune valeur interpolée, uniquement des littéraux à chaîne, vous pouvez obtenir ce que vous voulez simplement lire le fichier, plutôt que de devoir l'exécuter sur une pipe (backttick).
La raison pour laquelle cela ne fonctionne pas pour vous est B / C Ruby exécute ses commandes Si vous ne connaissez pas le nom du fichier source avant l'exécution, alors Réponse de la réponse est une bonne approche. Cependant, si vous connaissez le nom du fichier source à l'avance, vous pouvez faire un piratage rapide avec la ligne de hashbang. P> système code> dans des coquilles séparées. Ainsi, lorsque la commande système se termine, la coque qui avait acheté votre fichier se ferme et toutes les variables d'environnement définies dans cette coque sont oubliées.
% 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
Je suppose que la seule raison pour laquelle cela fonctionne, disons, CSH, c'est que vous utilisez la même instance Shell pour interpréter le script que vous recherchez. Donc, vous ne pouviez pas rechercher un fichier .CSH à partir d'un script Bash, plus que vous ne pouvez l'obtenir d'un script Ruby ...
Compte tenu de la rubis suivante
irb(main):019:0> source_env_from('test.sh') => {"FOO"=>"bar"} irb(main):020:0> ENV['FOO'] => "bar"
J'avais le même probrem. Et je résolve comme ci-dessous.
#!/usr/local/bin/ruby def source(filename) ENV.replace(eval(`tcsh -c 'source #{filename} && ruby -e "p ENV"'`)) end p "***old env*****************************" p ENV source "/file/I/want/to/source.csh" p "+++new env+++++++++++++++++++++++++++++" p ENV
Vous devez faire très attention si nom de fichier code> est en fait ce que vous vous attendez à ce que ce soit; S'il s'agit d'une entrée de l'utilisateur, il s'agit d'une énorme fuite de sécurité ... Vous ne voulez généralement pas consigner des fichiers arbitraires, de sorte qu'un moyen plus sûr de le faire pourrait être d'assumer
nom de fichier code> est un symbole, Et regardez cela dans un
hachage code> (et s'il n'existe pas, lancez une erreur).
Améliorer un peu sur la réponse de @ Takeccho ... Les chèques et quelques sifflets. Premièrement, l'environnement source est nettoyé via Théorie de l'opération: Lorsque Ruby sortit l'objet env en utilisant EDIT: env -i code>, qui est une mesure de sécurité mais pourrait ne pas être souhaitée dans certains cas. Deuxièmement, via
Set -A code>, toutes les variables définies dans le fichier sont "exportées" de la coque et donc importées en rubis. Ceci est utile pour la simulation / le comportement de simulation / dépassement trouvé dans les fichiers d'environnement utilisés avec des scripts init et SystemD env fichiers.
p code >, il le fait de manière à ce que Ruby puisse la lire en tant qu'objet. Nous utilisons donc la coquille pour rechercher le fichier cible et Ruby (dans une sous-coquille) pour émettre l'environnement de cette forme sérialisable. Nous capturons ensuite la sortie de Ruby et
eval code> dans notre processus de rubis. Il est clair que cela n'est pas sans risque, afin d'atténuer le risque, nous (1) validons le nom de fichier qui est transmis, et (2) valider à l'aide d'un regexp que la chose que nous recevons du Subshell-ruby est, en fait, une chaîne de hachage sérialisable. Une fois que nous en sommes sûrs, nous faisons le
eval code> qui crée un nouveau hachage. Nous fusionnons ensuite "manuellement" fusionnez le hash avec
env code>, qui est un objet
objet code> et non un
hash code>. S'il s'agissait d'un hachage, nous aurions pu utiliser la méthode
#merge! Code>. P>
SH -A CODE> EXPORTUÉS COMME
PATH < / code>. Nous devons également supprimer
shlvl code> et
pwd code> avant la fusion de hachage. P> p>
Qu'est-ce que vous obtenez si vous changez de script à cela? #! / usr / bin / env Fluby met env ['happytimes']
C'est une chose digne d'avoir accès aux fonctions de type OS telles que l'environnement de langues. Python a Os.environ, y a-t-il un module similaire à Ruby comme dans Python? cf Stackoverflow.com/Questtions/4906977/... & docs.python.org/2/library/os.html
Dupliqué possible de Shell sortant de Ruby tout en définissant une variable d'environnement a>