How to export a shell variable within a Perl script?

前端 未结 6 620
天涯浪人
天涯浪人 2020-12-19 10:37

I have a shell script, with a list of shell variables, which is executed before entering a programming environment.

I want to use a Perl script to enter the programm

相关标签:
6条回答
  • 2020-12-19 11:16

    Different sh -c processes will be called and environment variables are isolated within these.

    Also doesn't calling environment_defaults.sh also make another sh process within what these variables will be set to in isolation?

    Or start the Perl script with these environment variables exported and these will be set for all its child processes.

    0 讨论(0)
  • 2020-12-19 11:25

    But yes! It may be!

    #!/usr/bin/perl -w
    
    use strict;
    
    my $perldumpenv='perl -MData::Dumper -e '."'".
        '\$Data::Dumper::Terse=1;print Dumper(\%ENV);'."'";
    
    eval '%ENV=('.$1.')' if `bash -c "
            source environment_defaults.sh >/dev/null;
            $perldumpenv"`
        =~ /^\s*\{(.*)\}\s*$/mxs;
    
    system("obe");
    

    A little overkill as this runs a fork to a Perl-only-to-dump environment, but running Perl bind environment in a safe manner and Data::Dumper is the library to use for sending/storing and retrieving Perl variables.

    Nota: This don't care about security considerations: you have to trust environment_defaults.sh at same level as the main Perl script!!!

    0 讨论(0)
  • 2020-12-19 11:30

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

    use Env::Modify 'source';   # or use Env::Modify qw(source system);
    source("environment_defaults.sh");
    ... environment from  environment_defaults.sh  is now available
    ... to Perl and to the following 'system' call
    system("obe");
    
    0 讨论(0)
  • 2020-12-19 11:35

    (UPDATE: Oh, this is not exactly what you asked for, but it might be useful for someone.)

    If GDB is installed, you can set/modify parent shell variables with the following hack (non-strict style is used for clarity):

    #!/usr/bin/perl
    # export.pl
    
    use File::Temp qw( tempfile );
    
    %vars = (
        a => 3,
        b => 'pigs'
    );
    
    $ppid = getppid;
    
    my @putvars = map { "call putenv (\"$_=$vars{$_}\")" } keys %vars;
    
    $" = "\n";
    
    $cmds = <<EOF;
    attach $ppid
    @putvars
    detach
    quit
    EOF
    
    ($tmpfh, $tmpfn) = tempfile( UNLINK => 1 );
    print $tmpfh $cmds;
    
    `gdb -x $tmpfn`
    

    Test:

    $ echo "$a $b"
    
    $ ./export.pl 
    $ echo "$a $b"
    3 pigs
    
    0 讨论(0)
  • 2020-12-19 11:38

    When you call your second command, it's not done in the environment you modified in the first command. In fact, there is no environment remaining from the first command, because the shell used to invoke "environment_defaults.sh" has already exited.

    To keep the context of the first command in the second, invoke them in the same shell:

    system("source environment_defaults.sh && obe");
    

    Note that you need to invoke the shell script with source in order to perform its actions in the current shell, rather than invoking a new shell to execute them.

    Alternatively, modify your environment at the beginning of every shell (e.g. with .bash_profile, if using bash), or make your environment variable changes in perl itself:

    $ENV{FOO} = "hello";
    system('echo $FOO');
    
    0 讨论(0)
  • 2020-12-19 11:38

    Each process gets its own environment, and each time you call "system" it runs a new process. So, what you are doing won't work. You'll have to run both commands in a single process.

    Be aware, however, that after your Perl script exists, any environment variables it sets won't be available to you at the command line, because your Perl script is also a process with its own environment.

    0 讨论(0)
提交回复
热议问题