【问题标题】:Perl set and get env in different bash scriptPerl 在不同的 bash 脚本中设置和获取环境
【发布时间】:2015-11-03 05:50:07
【问题描述】:

我创建了一个调用两个 bash 脚本的 perl 脚本。第一个脚本将设置一个环境变量,第二个脚本将回显环境变量。我已经给出了下面文件的内容

# perlscript.pl

print `. setnameenv.sh`;
print `. getnameenv.sh`;

# setnameenv.sh

export my_msg='hello world!'

# getnameenv.sh

echo $my_msg

现在,当我运行 perl 脚本perl perlscript.pl 时,我希望在屏幕上打印“hello world”,但实际上我没有看到任何输出。我有什么方法可以在不修改 bash 脚本的情况下做到这一点?

【问题讨论】:

  • 子进程无法在父(Perl)进程中设置环境。因此,第一个孩子不能影响父母或第二个孩子的环境。
  • 有没有办法让父母知道孩子做了什么环境变化?

标签: linux bash perl shell unix


【解决方案1】:

您可以将 perl 嵌入到 bash 脚本中,

#!/bin/bash
. setnameenv.sh
exec perl -x "$0" "$@"

#!perl
# your script below

print `. getnameenv.sh`;

来自perldoc

-x -x目录 告诉 Perl 程序嵌入在更大的不相关文本块中,例如在邮件消息中。前导垃圾将被丢弃,直到以#开头的第一行!并包含字符串“perl”。将应用该行上任何有意义的开关。

【讨论】:

    【解决方案2】:

    你生成一个 shell,执行一些命令来改变它的环境,然后退出 shell。您从未使用过在退出 shell 之前创建的环境变量。如果你想让perl 看到它,你将不得不从那个 shell 启动 Perl。

    . setnameenv.sh ; perlscript.pl
    

    如果您无法更改perlscript.pl 的启动方式,您有几个选择,但都不是那么友好。一种选择是引导。

    BEGIN {
       if (!length($ENV{my_msg})) {
          require String::ShellQuote;
          my $cmd = join(' ; ',
             '. setnameenv.sh',
             String::ShellQuote::shell_quote($^X, $0, @ARGV),
          );
          exec($cmd)
             or die $!;
       }
    }
    

    【讨论】:

      【解决方案3】:

      现在可以在 Perl 中使用 Env::Modify module 完成此操作。

      use Env::Modify qw(source);
      
      source("setnameenv.sh");
      # env settings from setnameenv.sh are now available to Perl
      # and to the following  system  call
      
      print `. getenvname.sh`;   # or source again, like source("getenvname.sh")
      

      【讨论】:

        【解决方案4】:

        子进程可以继承父进程的环境,但不能做任何改变。同样,父母也无法访问孩子的环境。因此,要在父母中捕捉孩子的环境,孩子应该打印如下代码所示的值。下面的代码也会设置已经存在的环境变量,但这可以优化

        # perlscript.pl
        
        my $env_val = `. setnameenv.sh; env`;
        my @env_list = split "\n", $env_str;
        
        foreach (@env_list)
        {
           /([\w_]+)=(.*)/;
           $ENV{$1} = $2;
        }
        
        print `. getnameenv.sh`;
        

        SO answer中找到真正的解释

        【讨论】:

          【解决方案5】:

          仅为子进程导出变量。

          您不能将变量导出回父进程。

          您需要另一种方式将变量传回给父亲或兄弟。

          例如,这是一个示例,其中所有导出的变量都保存并从文件中读取:

          #!/bin/dash
          # setnameenv.sh
          
          export my_msg='hello world!'
          
          export > savedVariables.sh
          

          #!/bin/dash
          # getnameenv.sh
          
          . ./savedVariables.sh
          
          echo "$my_msg"
          

          注意:这适用于破折号。 bash 生成一行他无法读回。

          【讨论】:

            猜你喜欢
            • 2011-02-12
            • 2013-10-26
            • 2013-11-15
            • 2021-12-16
            • 2017-10-26
            • 2016-10-07
            • 1970-01-01
            • 1970-01-01
            • 2011-11-13
            相关资源
            最近更新 更多