2012-11-15 105 views
5

我想使用Perl设置环境变量。它应该在外部(在当前shell)输出这个变量,而不仅仅是在脚本中。使用perl设置环境变量

我想:

`setenv X1 /p/fsd` 

system("setenv X1 /p/fsd") == 0 or die "failed:$?" 

system command "setenv X1 /p/fsd" failed: -1 

$ENV{"X1"} = "/p/fsd"; 

一切似乎是工作。

如果有关系,我正在使用TCSH。

+0

[通过Perl脚本设置环境变量]可能的重复(http://stackoverflow.com/questions/19192682/setting-an-environment-variable-through-a-perl-script) –

回答

10
$ENV{"X1"} = "/p/fsd"; 

是正确的方法。

测试中perlconsole

Perl> $ENV{X1} = "/p/fsd"; 
/p/fsd 

Perl> system('echo $X1'); 
/p/fsd 
0 

注意

+0

这只会工作脚本正在运行,对吗?一旦脚本停止,它们就消失了。我想要做的是我在SHELL中有10-15个环境变量,并且他们经常更新。所以,而不是我手动设置他们..我正在想它的脚本。 – user1793023

+0

这是subhell的原理。如果你杀了父亲,你也杀了儿子,这很伤心,但这就是生活。 –

+0

增加了有关子壳和父母解释的链接。 –

3

因为在setenv X1 /p/fsd没有特殊字符,

system("setenv X1 /p/fsd") 

相当于

system("setenv", "X1", "/p/fsd") 

它的失败,因为有是没有名为setenv的程序。如果此优化不存在,则会得到不同的结果*。在这种情况下,

system("setenv X1 /p/fsd") 

将相当于

system("sh", "-c", "setenv X1 /p/fsd") 

这是行不通的或者是因为sh没有setenv命令。所以你可以运行下面的代码:

system("tcsh", "-c", "setenv X1 /p/fsd") 

但它是没有意义的。你会创建一个shell,设置其中的一个变量。然后shell退出并且其变量不复存在。

如果你想设置的Perl和它的孩子看到的环境变量,只需使用

$ENV{X1} = "/p/fsd";   # Until end of program 

local $ENV{X1} = "/p/fsd"; # Until end of scope 

* —优化的代码不应该具有不同的行为未优化代码,但是由于优化只是改变了你得到的错误,这是可以接受的。

1

正如其他回复所述,您不能在父项中设置一个环境变量。但是,您可以在perl中执行一些复杂的操作,然后将最终结果传回给要设置的shell。例如,在tcsh

eval `perl -le 'print q(setenv X1 /p/fsd)'` 

你能做出这样的感觉有一点透明的,例如,

alias x1.pl 'eval `x1.pl`' 
+0

'ssh-agent'有同样的问题(设置环境变量调用shell)并使用相同的'eval'技巧。它甚至可以在'sh'和'csh'('-s'或''-c'')中切换不同的setenv语法。 –

2

同样重要的是要知道如何设置环境变量是如何将其删除:

delete $ENV{"X1"}; 

这将删除perl进程和任何子进程的环境变量。但环境变量仍将为父进程设置。

+0

它应该是*“X1”*还是* X1 *? –

+0

@PeterMortensen这些是等同的。一般来说,我们省略了引号,因为它更简单。尤其是对于环境变量,因为它们都是大写字母,并且没有特殊字符如果您使用奇怪的特殊字符,则可能需要引号。看[这个讨论](http://stackoverflow.com/questions/401556/are-quotes-around-hash-keys-a-good-practice-in-perl) – mareoraft