Debaditya
Debaditya

Reputation: 2497

Export variable from a shell script into a perl script

Perl Code

`. /home/chronicles/logon.sh `; 

print "DATA  : $ENV{ID}\n";

In logon.sh , we are exporting the variable "ID" (sourcing of shell script).

Manual run

$> . /home/chronicles/logon.sh
$> echo $LOG

While I am running in terminal manually (not from script). I am getting the output. (But not working from the script)

I followed this post :

How to export a shell variable within a Perl script?

But didnt solve the problem.

Note

I am not allowed to change "logon.sh" script.

Upvotes: 1

Views: 3573

Answers (6)

mob
mob

Reputation: 118605

This can now be done with the Env::Modify module

use Env::Modify 'source';
source("/home/chronicles/logon.sh");
... environment setup in logon.sh is now available to Perl ...

Upvotes: 1

F. Hauri  - Give Up GitHub
F. Hauri - Give Up GitHub

Reputation: 70832

Well, I've find a solution, that sound nice for me: This seem robust, as this use widely tested mechanism to bind shell environment to perl (running perl) and robust library to export them in a perl variable syntax for re-injecting in root perl session.

The line export COLOR tty was usefull to ask my bash to export newer variables... This seem work fine.

#!/usr/bin/perl -w

my $perldumpenv='perl -MData::Dumper -e '."'".
    '\$Data::Dumper::Terse=1;print Dumper(\%ENV);'."'";

eval '%ENV=('.$1.')' if `bash -c "
        . ./home/chronicles/logon.sh;
        export COLOR tty ID;
        $perldumpenv"`
    =~ /^\s*\{(.*)\}\s*$/mxs;

# map { printf "%-30s::%s\n",$_,$ENV{$_} } keys %ENV;
printf "%s\n", $ENV{'ID'};

Anyway, if you don't have access to logon.sh, you have to trust it before running such a solution.

Old...

There is my first post... for history purpose, don't look further.

The only way is to parse result command, while asking command to dump environ:

my @lines=split("\n",`. /home/chronicles/logon.sh;set`);

map { $ENV{$1}=$2 if /^([^ =])=(.*)$/; } @lines;

Upvotes: 1

Giuliani Sanches
Giuliani Sanches

Reputation: 672

You could do something like:

#/usr/bin/perl

use strict;
use warnings;

chomp(my @values = `. myscript.sh; env`);

foreach my $value (@values) {
    my ($k, $v) = split /=/, $value;
    $ENV{$k} = $v;
}

foreach my $key (keys %ENV) {
    print "$key => $ENV{$key}\n";
}

Upvotes: 1

amon
amon

Reputation: 57640

The script inside the backticks is executed in a child process. While environment variables are inherited from parent processes, the parent can't access the environment of child processes.

However, you could return the contents of the child environment variable and put it into a Perl variable like

use strict; use warnings; use feature 'say';
my $var = `ID=42; echo \$ID`;
chomp $var;
say "DATA: $var";

output:

DATA: 42

Here an example shell session:

$ cat test_script
echo foo
export test_var=42
$ perl -E'my $cmd = q(test_var=0; . test_script >/dev/null; echo $test_var); my $var = qx($cmd); chomp $var; say "DATA: $var"'
DATA: 42

The normal output is redirected into /dev/null, so only the echo $test_var shows.

Upvotes: 2

Charles Engelke
Charles Engelke

Reputation: 5649

Your Perl process is the parent of the shell process, so it won't inherit environment variables from it. Inheritance works the other way, from parent to child.

But when you run the script with backticks, as shown, the standard output of the script is returned to the Perl script. So, either modify the shell script to end with the echo $LOG statement you show, or create a new shell script that runs the login.sh and then has echo $LOG. Your Perl script would then be:

my $value = `./myscript.sh`;
print $value;

Upvotes: 0

melvinto
melvinto

Reputation: 389

It won't work.

An environment variable can't be inherited from a child process.

The environment variable can be updated in your "manual run" is because it's in the same "bash" process.

Source command is just to run every command in login.sh under current shell.

More info you can refer to: can we source a shell script in perl script

Upvotes: 1

Related Questions