2012-11-15 412 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