Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Perl脚本中重新加载Bash环境变量?_Bash_Perl - Fatal编程技术网

如何在Perl脚本中重新加载Bash环境变量?

如何在Perl脚本中重新加载Bash环境变量?,bash,perl,Bash,Perl,有没有一种方法可以从Perl脚本中加载Bash环境变量(通过从Bash shell中获取~/.bashrc来定义)。具体来说,我感兴趣的是在Perl脚本的调用方不是bashprocess1的子对象的情况下重新加载PERL5LIB环境变量。在这种情况下,$ENV{PERL5LIB}将不存在,这将阻止我使用我在主目录中安装的任何模块 第一次尝试可以是使用-l选项在bash下重新运行我自己。这将加载~/.bash\u profile,我已将该文件设置为加载~/.bashrc #! /usr/bin/e

有没有一种方法可以从Perl脚本中加载Bash环境变量(通过从Bash shell中获取
~/.bashrc
来定义)。具体来说,我感兴趣的是在Perl脚本的调用方不是
bash
process1的子对象的情况下重新加载
PERL5LIB
环境变量。在这种情况下,
$ENV{PERL5LIB}
将不存在,这将阻止我使用我在主目录中安装的任何模块

第一次尝试可以是使用
-l
选项在
bash
下重新运行我自己。这将加载
~/.bash\u profile
,我已将该文件设置为加载
~/.bashrc

#! /usr/bin/env perl

use strict;
use warnings;

if ( !exists $ENV{PERL5LIB} ) {    
    exec 'bash', '-lc', $0, @ARGV;
}
else {
    # Main program starts here..
}
但是,对于
~/.bashrc
中未定义
PERL5LIB
的(意外)情况,这可能会进入无限循环

脚注:

[1] 我在尝试使用google chrome扩展API从
google chrome
进程编写要调用的本机主机时遇到了这种特殊情况。 可以通过shell脚本修改您的环境

差不多

use Env::Modify 'source';

# BEGIN { ???
if (!exists($ENV{PERL5LIB})) {
    source("$ENV{HOME}/.bashrc");
    die "PERL5LIB not in .bashrc" unless $ENV{PERL5LIB};
    exec($^X, $0, @ARGV);     # restart
}
(显然,使用Getopt::Long或类似的方法会更好。)

这不仅符合您的规范,而且在需要时提供了一个旁路


也就是说,整个概念是有缺陷的。大多数人不应该使用PERL5LIB,修复配置不好的系统(那些需要PERL5LIB但在应该设置时没有设置PERL5LIB的系统)也不是你的工作。相反,.

听起来您的扩展应该在扩展本身的同时安装任何非标准库,然后您可以硬编码(相对)路径,并在启动时将其添加到
@INC
,而不需要用户管理它(以及您的库与他们实际需要的库之间可能存在的冲突)。如果您只想从主目录加载模块,那么为什么不在主目录上使用
lib
,而不依赖环境变量?您的脚本甚至不知道调用方是否使用
bash
;调用时,调用方有责任确保
PERL5LIB
具有适当的值g脚本。@chepner在我的用例中,调用者是
google chrome
,我同意奇怪的是,它没有为其子进程设置
PERL5LIB
。也就是说,
PERL5LIB
可能应该从
.bash\u profile
中定义一次并继承,而不是每次设置interactive shell已启动。不过,我不知道
google chrome
是否是从您的登录shell中派生的进程启动的。谢谢,但现在的问题是
Env::Modify
也安装在我的主目录中(我使用的是
cpanm
)。谢谢你的代码。但是我很难理解它。传递给
bash
的参数:为什么
$0
传递了两次?以及
$@
在做什么?脚本后的第一个参数被放入
$0
,下一个在
$1
中,下一个在
$2
中,等等。
“$@”
相当于
“$1”“$2”“$3”“。
。请注意,我们不使用
$0
,因此可以为其传递任何值。请将
bash-c echo foo bar
bash-c'$@”进行比较“dummy echo foo bar
谢谢,现在对我来说很有意义。但是为什么我们不应该使用
PERL5LIB
?我一直在使用它。首先,我安装
cpan App::cpanminus
;在这个初始安装
时,cpan
会询问我是在我的主目录还是在系统目录中安装(需要root权限)。我总是选择在我的主目录中安装。然后,我需要设置PERL5LIB。事实上,如果您配置了
cpanm
,那么您也配置了
cpan
。@HåkonHægland您的发行版已经安装了许多模块,因此不可能只使用cpan。您不会经常看到问题,但它们确实存在没有理由冒这种不必要的风险,因为安装额外的perl副本非常容易。您应该发布关于perlbrew问题的另一个问题。
#! /usr/bin/env perl

use strict;
use warnings;

BEGIN {
    if (!exists( $ENV{PERL5LIB} )) {    
        if (!@ARGV || $ARGV[0] ne '--no-restart') {
            exec('bash', '-lc', '"$@"', $0, $^X, $0, '--no-restart', @ARGV);
        }
    }

    if (@ARGV && $ARGV[0] eq '--no-restart') {
        shift(@ARGV);
    }
}

...