Have perl execute shellscript & take over env vars

I have a shell script that does nothing but a set of environment variables:

export MYROOTDIR=/home/myuser/mytools export PATH=$MYROOTDIR/bin:$PATH export MYVERSION=0.4a 

I have a perl script and I want the perl script to somehow get the perl script to work with the env vars specified in the shell script. I need this to happen from within the perl script, although I don't want the calling perlscript user to manually run shellscript first.

When trying to run

 system("sh myshell.sh") 

env vars are not "propagated" until the process running the perl script.

Is there any way to do this?

+4
source share
5 answers
+1
source

To answer this question correctly, I need to know a little more.

  • Is it possible to run a shell script from within a perl script?
  • Do all forms assign export VAR=value to variables (i.e., with fixed assignments, without variable substitutions or command substitutions)?
  • Does the shell script use anything else but assign variables?

Depending on the answers to them, there are various options for complexity.

Thanks for clarifying. Ok, here's how to do it. Besides assigning variables, your script has no side effects. This allows you to run the script from within perl. How to find out which variables are exported to a script? We could try to parse the shell of the script, but this is not a Unix way of using tools that do something well, and combine them. Instead, we use the shell export -p command to declare all exported variables and their values. To find only the variables actually set by the script, and not all the other noises, the script is run in a clean environment using env -i , another underrated POSIX jewel.

Putting it all together:

 #!/usr/bin/env perl use strict; use warnings; my @cmd = ( "env", "-i", "PATH=$ENV{PATH}", "sh", "-c", ". ./myshell.sh; export -p" ); open (my $SCRIPT, '-|', @cmd) or die; while (<$SCRIPT>) { next unless /^export ([^=]*)=(.*)/; print "\$ENV{$1} = '$2'\n"; $ENV{$1} = $2; } close $SCRIPT; 

Notes:

  • You need to go into env -i whole environment your myshell.sh needs, for example. PATH
  • Shells usually export the PWD variable; if you do not want this in your Perl ENV hash, add next if $1 eq 'PWD'; after the first next .

That should do the trick. Let me know if this works.

See also:

+4
source

You can set environment variables inside the BEGIN block. The BEGIN block runs to the rest of the code; setting environment variables in this block makes them visible to the rest of the code before it is compiled and run. If you have any perl modules to β€œuse” based on enviornment settings, the BEGIN block makes this possible.

Perl uses a special% ENV hash to support environment variables. You can modify the contents of this hash to set env variables.

EXAMPLE:

 BEGIN { $ENV { 'MYROOTDIR' } = '/home/myuser/mytools'; $ENV { 'PATH' } = "$ENV{ 'MYROOTDIR' }/bin:$ENV{ 'PATH' }"; } 
0
source

Wouldn't it be easier to install a shell script to set variables and then call the perl program?

i.e:.

run.sh:

 #!/bin/sh export MYROOTDIR=/home/myuser/mytools export PATH=$MYROOTDIR/bin:$PATH export MYVERSION=0.4a ./program.pl 
0
source

This can now be done with Env::Modify with minor changes to your existing code.

 use Env::Modify 'system'; ... system("sh myshell.sh"); print $ENV{MYROOTDIR}; # "/home/myuser/mytools" 

or if your entire shell script does this, change the environment, you can use the source function

 use Env::Modify `source`; source("myshell.sh"); print $ENV{MYVERSION}; # "0.4a" 
0
source

Source: https://habr.com/ru/post/1347423/


All Articles