2011-07-26 32 views

回答

14

子環境不能改變父環境。最好的辦法是在%ENV從Perl代碼內部解析env.sh並設置變量:

#!/usr/bin/perl 

use strict; 
use warnings; 

sub source { 
    my $name = shift; 

    open my $fh, "<", $name 
     or die "could not open $name: $!"; 

    while (<$fh>) { 
     chomp; 
     my ($k, $v) = split /=/, $_, 2; 
     $v =~ s/^(['"])(.*)\1/$2/; #' fix highlighter 
     $v =~ s/\$([a-zA-Z]\w*)/$ENV{$1}/g; 
     $v =~ s/`(.*?)`/`$1`/ge; #dangerous 
     $ENV{$k} = $v; 
    } 
} 

source "env.sh"; 

for my $k (qw/foo bar baz quux/) { 
    print "$k => $ENV{$k}\n"; 
} 

鑑於

foo=5 
bar=10 
baz="$foo$bar" 
quux=`date +%Y%m%d` 

它打印

foo => 5 
bar => 10 
baz => 510 
quux => 20110726 

的代碼只能處理簡單的文件(例如,它不處理if報表或foo=$(date))。如果你需要更復雜的東西,那麼首先爲你的Perl腳本編寫一個包裝器,這個包裝器首先是正確的選擇(這也可能是首先要解決的問題)。

在執行Perl腳本之前源env.sh的另一個原因是在Perl中設置環境變量對於期望看到它們的模塊來說可能發生得太晚。

在文件foo

#!/bin/bash 

source env.sh 

exec foo.real 

其中foo.real是你的Perl腳本。

2

您可以使用任意複雜的shell腳本,通過使用相關shell執行它們,將它們的環境轉儲到同一進程中的標準輸出,然後解析perl中的腳本。將輸出提供給%ENV以外的內容或針對感興趣的特定值進行過濾是謹慎的,因此您不要更改PATH等可能在其他地方產生有趣副作用的內容。我已經放棄了衍生shell腳本的標準輸出和錯誤,雖然它們可以被重定向到臨時文件並用於perl腳本中的診斷輸出。

foo.pl:

#!/usr/bin/perl 
open SOURCE, "bash -c '. foo.sh >& /dev/null; env'|" or 
die "Can't fork: $!"; 

while(<SOURCE>) { 
if (/^(BAR|BAZ)=(.*)/) { 
    $ENV{$1} = ${2} ; 
} 
} 

close SOURCE; 

print $ENV{'BAR'} . "\n"; 

foo.sh: 出口BAR =巴茲

+0

'env'的使用僅在shell腳本故意導出變量的情況下有效。如果腳本沒有專門導出它們,請嘗試'設置'而不是'env'。 – EdwinW

2

嘗試此(UNIX代碼樣品):

坎德拉/ TMP

VI小號

#!/bin/bash 
export blah=test 

六噸

#!/usr/bin/perl 

if ($ARGV[0]) { 
    print "ENV second call is : $ENV{blah}\n"; 
} else { 
    print "ENV first call is : $ENV{blah}\n"; 
    exec(". /tmp/s; /tmp/t 1"); 
} 

搭配chmod 777式T

。/噸

ENV第一個電話是:

ENV第二個電話是:測試

訣竅是使用exec先源的bash腳本,然後調用你的Perl腳本再次與參數,所以你知道你第二次被召喚。

相關問題