【问题标题】:how to set env variables which are in csh script from the perl script for the current terminal?如何从当前终端的 perl 脚本设置 csh 脚本中的环境变量?
【发布时间】:2019-07-31 12:21:05
【问题描述】:

我正在使用*.csh 文件将环境变量设置为当前终端。当我在 perl 脚本中使用 system("/bin/tcsh *.csh") 时,*csh 文件正在执行但未将任何环境变量设置到当前终端。

当我在 perl 脚本中使用 system("/bin/tcsh *.csh") 时,*csh 文件正在执行但未将任何环境变量设置到当前终端。

sub veloce_env_setup_sub {
    printf "\n\n\t -veloce_env_setup  option enabled\n";
    system("/bin/tcsh /proj/I2BZA1/users/ssudi/SCRIPTS/veloce_env/vlab_4p4p0/veloce_setup.csh");
}
  • 预期:在获取 *.csh 文件后,环境变量应设置为当前终端。

  • 实际结果:只有打印开始,但未将环境变量设置到当前终端。

【问题讨论】:

标签: perl csh


【解决方案1】:

perldoc -q environment:

我在 perl 脚本中{更改了目录,修改了我的环境}。当我退出脚本时,更改为什么消失了?如何让我的更改可见?

Unix

从最严格的意义上说,它是无法完成的——脚本作为与它启动时所在的 shell 不同的进程执行。对流程的更改不会反映在其父进程中 - 只会反映在更改后创建的任何子进程中。有一种 shell 魔法可以让你通过eval()在你的 shell 中输出脚本的输出来伪造它;详情请查看 comp.unix.questions 常见问题解答。

在您的代码中,问题出现了两次:

  1. system 生成 tcsh,它运行一个设置环境变量的脚本。这些环境变量只存在于tcsh 进程中。当system返回时(即tcsh退出时),子进程的环境就消失了。

  2. 即使您设法修改了 perl 脚本的环境(您可以通过分配给 %ENV 来完成),这也不会影响启动 perl 的父 shell。

【讨论】:

    【解决方案2】:

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

    use Env::Modify qw(:tcsh source);
    
    sub veloce_env_setup_sub {
        printf "\n\n\t -veloce_env_setup  option enabled\n";
        source("/proj/I2BZA1/users/ssudi/SCRIPTS/veloce_env/vlab_4p4p0/veloce_setup.csh");
    }
    

    【讨论】:

    • [ssudi@polhyadcvnc ~/COMMON_SCRIPTS_SAM]$ ./main.pl -veloce_env_setup 在@INC 中找不到Env/Modify.pm(@INC 包含:/usr/local/lib64/perl5/ usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at ./main.pl line 4. BEGIN failed--编译在 ./main.pl 第 4 行中止。
    【解决方案3】:

    子进程的环境不影响父进程的环境。也就是说,您启动的进程不会改变启动它的事物的环境。

    如果您想为 Perl 脚本设置环境,您有一些选择。哪一个最适合您取决于您​​要做什么。

    1. 在 Perl 中设置选项。无需使用 shell 程序,而是在 Perl 中通过在 %ENV 散列中设置值来完成这一切。如果您只需要该程序,这很有效。很可能,无论您在 tcsh 中做什么,Perl 都可以做到。

    2. 不要从 Perl 调用 shell 脚本,而是从 shell 脚本调用您的 Perl 程序。现在 shell 脚本是父进程,子进程(Perl 程序)继承父进程的环境。

    #!tcsh
    setenv SOME_VALUE foo
    perl my_program
    
    1. 在子进程中,您可以打印环境并从父进程中读取。你会解析它并适当地转换它。这就是 Env::Modify 模块的作用,但我不希望这是我的第一选择。

    【讨论】:

      【解决方案4】:

      您无法访问已由子进程设置的进程中的环境变量。这是流程如何工作的基本属性。

      【讨论】:

        【解决方案5】:

        你可以设置 %ENV{'your_choice'} = 'as you like';在 Perl 中。

        当然,它看起来有点像 hartverdrahtet (yt),但它又很好用了。所以环境是心理上的,只是在顶级实例脚本的头脑中,并在关闭它时关闭并删除。

        另一种方法是调用 system("set VARIABLE=VALUE"); 这里变量在关闭后保留,直到下次重新启动。

        【讨论】:

          猜你喜欢
          • 2023-03-03
          • 2011-03-05
          • 1970-01-01
          • 1970-01-01
          • 2014-01-29
          • 2012-01-19
          • 2016-10-07
          • 1970-01-01
          相关资源
          最近更新 更多