2010-08-05 120 views
2

我的問題是,當我運行以下它會說bash腳本已成​​功完成。但它不會等待腳本完成,如果它早退了,它將移動它所需的文件。那麼我在做什麼錯誤,它不會等待後臺進程完成移動文件?Perl:等待後臺進程完成

my $pid = fork(); 
    if($pid == -1){ 
    die; 
    } elsif ($pid == 0){ 
    #system(@autoDeploy) or die; 
    logit("Running auto deploy for $bundleApp"); 
    exec("./deployer -d $domain.$enviro -e $enviro >> /tmp/$domain.$enviro &") 
        or logit("Couldnt run the script."); 
    } 
    while (wait() != -1){ 

    } 
    logit("Ran autoDeploy"); 

    logit("Moving $bundleApp, to $bundleDir/old/$bundleApp.$date.bundle"); 
    move("$bundleDir/$bundleApp", "$bundleDir/old/$bundleApp.$date.bundle"); 
    delete $curBundles{$bundleApp}; 

回答

5

最簡單的做法是在exec命令行的末尾使用& - 這意味着您分叉兩次,並且您的wait處理將立即退出。

我實際上沒有看到什麼目的fork/exec是服務你都在這裏,不過,如果你不是重定向I/O和沒有做任何事情,而是要等待exec「d進程結束;這就是system的用途。

system("./deployer -d $domain.$enviro -e $enviro >> /tmp/$domain.$enviro") 
       and logit("Problem running deployer: $?"); 

將很容易地取代前12行代碼。

並且正如傳遞中的注意,fork在失敗時不會返回-1;它返回undef,所以整個檢查完全是假的。

+0

所以system()所有就緒都在後臺運行bash腳本? – 2010-08-05 14:18:14

+0

如果在子進程中使用'system'而不是'exec',則可能需要顯式調用'exit',以便子代不會重新運行僅在父進程中運行的代碼。 – mob 2010-08-05 15:00:59

+0

@Nerdtastic - 您在子進程中調用了'fork',然後調用'exec'(或'system'),所以是的,該命令將在後臺運行。 – mob 2010-08-05 15:03:44

1

你並不需要在你的exec參數使用&,因爲你已經是一個叉下運行。

+0

這是否仍然在後臺運行?我看到我是否會等待這個過程。 – 2010-08-05 14:14:43

+0

你想等待這個過程還是你不想等待這個過程?如果你不想等待這個過程,爲什麼你的原始代碼示例有一個「等待」,爲什麼你抱怨那個等待不起作用的副作用?聽起來就像你想等着我... – hobbs 2010-08-05 14:28:36

+0

是的,我非常感謝。 – 2010-08-05 14:30:21