2012-11-30 18 views
1

您可以讀取的環境變量有沒有辦法在Perl中設置環境變量var並將其從腳本範圍中導出?

$envVarVal = $ENV{'VAR_NAME'}; 

反向設置它不工作,即你將看不到變種一旦腳本完成運行:

$ENV{'VAR_NAME'} = 'some_val'; 

我也嘗試了系統調用:

`export VAR_NAME=some_val`; 

該調用在Perl腳本中成功,但該變量再次超出範圍。

是否有可能做到這一點,如果沒有,爲什麼不可能在Perl中完成,但是通過採購一個常規shell腳本,任何shell,據我所知?

+0

你需要怎樣處理導出的值?你是否試圖將它添加到啓動Perl程序的shell中,還是需要它對Perl程序啓動的子進程可見? –

回答

8

這是不可能的on most systems,不僅在perl中,而且在shell中也是如此。每個進程都會從父進程繼承它自己的環境副本,並且環境的任何更改僅影響該進程及其創建的任何子進程(在對環境進行更改之後)。

設置在perl中的環境變量爲$ENV{VAR_NAME} = 'some_val';將可用於由perl腳本創建的進程。就像shell16腳本使用export VAR_NAME=some_val設置的環境變量將反映在該腳本後面創建的任何進程中。

甲殼函數或輸出一個外殼腳本(使用source scriptname. scriptname)可以更改該活得比功能或執行的腳本環境中。但這是唯一可能的,因爲沒有新的進程被創建來運行該代碼,它將在它被調用的相同進程內運行。

使用perl的反引號運算符運行export是毫無意義的。這將成功,因爲這將導致perl啓動一個新的shell進程,在該進程中設置了環境變量,但是那個進程會立即退出而沒有做任何有用的事情。

通過使用echo $$來顯示進程ID,您可以在某種程度上看到這一點。在運行之前,嘗試一下腳本,在你的源腳本中運行腳本,運行相同的腳本而不使用腳本,以及在使用perl的反引號操作符執行的shell代碼內運行腳本。進程ID也可以使用print $$, "\n";從perl打印。

+0

對不起,我的意思是尋找一個普通的shell腳本。在OP – amphibient

+0

中進行了更正。發出shell腳本與使用shell函數類似。這不會創建一個新的過程。我已經更新我的答案來解決這個問題。 – qqx

6

這是不可能的。但是,您可以讓Perl爲您創建一個腳本,然後將其源代碼或評估它:

#!/bin/bash 
eval $(perl -e 'print "VAR1=", rand 1') 
perl -e 'print "VAR2=", rand 1' > var2.sh 
. var2.sh 
rm var2.sh 
echo $VAR1 $VAR2 
13

是的,使用VMS。

這可能不是最實際的建議,但它是完整的。 :)

VMS是...不同。 VMS和Unix可能與Windows和Unix更爲不同。 Perl是圍繞Unix思維構建的,必須將這些Unix概念中的一些延伸到突破點,以便將它們包裝在VMS的做事方式中。其中之一就是%ENV的含義。

從Unix的角度來看,VMS沒有環境變量。 VMS最接近的是logical names。它們是一個鍵/值對的表格,其用途類似於環境變量和shell別名。與Unix上的環境變量不同,像Ogres一樣,它們有層。

The OpenVMS Consultant: Logical Names (Part 1)

大多數過程與至少四個邏輯名稱表(進程,作業,組和系統)相關聯。名稱通常通過首先按層次順序搜索Process,Job,Group和System表來進行翻譯。高級用戶可以控制搜索和翻譯過程。此外,出於安全性和完整性原因,某些翻譯會排除最終用戶定義的邏輯名稱。

在Unix上,環境表是複製到一個過程,因此這個過程會不會對其父母任何影響。在VMS上,邏輯表是一個堆棧。 VMS讀取堆棧直到找到一個值。例如,如果詢問SYS$OUTPUT(與STDOUT類似)的值,它將首先檢查進程的邏輯表,然後檢查作業,然後檢查組,最後檢查整個系統的值。通過這種方式,操作系統可以在系統表中定義一個默認的SYS$OUTPUT,但它可以被您或一個進程覆蓋。

如果這看起來很複雜,其實際上簡化爲what really happens

邏輯是一個堆棧,所以如果你設置一個,會發生什麼?

最後,爲了回答這個問題,$ENV{FOO} = "BAR"將查找邏輯表堆棧並將其分配給它找到的第一個FOO。如果在流程表中有一個,它將分配給它。如果工作表中有一個,它將分配給它。依此類推,直到達到允許寫入的極限。此時,它將在其最高表中創建一個新條目,可能是作業表。這意味着$ENV{FOO} = "BAR"很可能會在工作表中登陸,因此您的所有流程都可以看到。

這就是在一個進程中如何在Perl中設置環境變量並將其導出到另一個進程的方式。

+2

-1與@ choroba的技術相比不切實際,+1在盒子外面 – mob

相關問題