2011-12-08 62 views
1

您好我將如何退出在Linux機器上使用qx //在perl中啓動的已完成的進程?在Perl中啓動的退出進程

我正在考慮調用ps來查找PID並調用kill來退出。但我想知道是否有更簡單的方法來做到這一點。

感謝

+0

你做我的'$ S = QX/some_command /;'你的Perl腳本,你想手動殺'some_command'使你的腳本可以相處嗎? –

+0

是的,這是我想要做的。我有一個我正在調用的Java Jar,我想在完成處理後立即退出它。 – urbanspr1nter

+1

但是'qx //'在進程退出時立即返回,並且當完成時您的jar應該退出。除非卡住,否則不應該殺死'qx //'進程。我錯過了什麼? –

回答

1

你可以使用

pkill -o -u urbanspr1nter -f some_command 

pgrep ... | xargs ps代替pkill先審查。

+0

您不能在Perl腳本中運行它,因爲腳本阻塞直到過程結束。但是,如果從shell運行,它將工作。 – Jonathan

+0

@Jonathan:不錯,謝謝。從我的答案中刪除它。 – flesk

+0

謝謝,這個工程! – urbanspr1nter

4

如果它與qx//一起啓動並且已經完成,則不需要殺死它,它已經消失。我懷疑你的實際上可能會卡住:沒有完成流程明智的,但沒有做任何有用的東西了。

沒有任何東西可以直接從操作的Perl端執行。 qx//是一個同步呼叫。它期望它啓動的進程終止,它唯一的返回碼是進程的標準輸出轉儲。 (勉強,也通過$?返回代碼)

它不是爲了產生後臺進程。因此,它不允許您訪問孩子的PID,更不用說控制工作。

所以你的情況,如果是一次性的問題,你只需要找到並通過psgrepkillpgreppkill適合你的思維最好的方式組合的任何終止錯誤的過程。如果這是一個經常出現的問題,那麼您應該從內建qx//設施遷移到一些能讓您更好控制的設施。例如,IPC::Run提供超時。

3

我認爲real你想問的問題是「我如何在後臺啓動一個進程(以後可能會殺掉它)?」

最簡單的解決方案是open來自過程的管道。因此,而不是

my $output = qx/some_command/; 
# do something with $output 

你會做

my $pid = open my $pipe, "some_command |" or die $!; 
while (my $line = <$pipe>) { 
    # do something with $line 
    last if some_condition(); 
} 
close $pipe or $! and die $!; 

如果close的子進程結束前的管道,它會嘗試輸出不同的是,下一次會收到一個SIGPIPE信號,這將通常會殺死它。如果您懷疑該流程可能會繼續運行而沒有會產生任何輸出,您可以kill手動使用它。

kill $pid, 1; # 1 == SIGHUP on most Unix systems 

(你應該關閉的管道,因爲close將等待進程結束做到這一點之前。)

但請注意,如果找不到Perl不得不調用一個shell來解析您的命令,由open返回的進程ID將是shell的進程ID,而不是實際的命令。您可以通過使用open多參數形式避免這種情況:

my $pid = open my $pipe, '-|', $command, @command_args or die $!;