外部プログラムを実行して停止する perl スクリプトを作成しようとしています。
外部プログラムは、それが実行されているコマンド シェルで「Enter」を押すことになっているため、それ自体では停止しません。
perlスクリプトで外部プログラムを停止する方法はありますか?
外部プログラムを実行して停止する perl スクリプトを作成しようとしています。
外部プログラムは、それが実行されているコマンド シェルで「Enter」を押すことになっているため、それ自体では停止しません。
perlスクリプトで外部プログラムを停止する方法はありますか?
perlスクリプトで外部プログラムを停止する方法はありますか?
一言で言えば、そうです。ただし、実装は、アプリケーションを実行しているプラットフォームによって異なります。
system()
perl がサポートするすべてのプラットフォームで、外部プログラムを呼び出すために使用できます。ただし、元のプログラムは外部プログラムが終了するまで待機して何もsystem()
しないため、状況に適合しません。
プラットフォーム (OS) について言及しなかったため、ここでは 2 つの主要なプラットフォームについて説明する必要があります。
Unix ライクな OS: まずfork
、子プロセスを作成し、子プロセスでexec
外部プログラムを呼び出すことができます。次に、親プロセスで子プロセスを待機しTERM
、外部プログラムを停止したいときにシグナル(またはデフォルトでプロセスを終了する他のシグナル)を送信できます。
if (($pid = fork) == 0) {
exec("$external_program $arg");
} else {
# do something...
kill "TERM", $pid;
}
Win32 OS: Win32 プラットフォームでは、子プロセスfork
ed は実際には疑似プロセスであり、Win32 は Unix のようなシグナル方式をサポートしていません。Win32のソリューションに従うこともできますが、1
私が試した限り、子プロセスは、たとえば、子プロセスがスリープ状態であるかソケット接続を待機している場合など、シグナルを見逃すことがよくあります。これは非常に不安定になる可能性があります。
代わりに、Win32::Processの方が優れたソリューションです。Win32 API を使用して、プロセスを作成および操作します。
use Win32::Process;
use Win32;
Win32::Process::Create($ProcessObj, $external_program, $arg,
0, NORMAL_PRIORITY_CLASS, ".") or die;
# do something ...
$ProcessObj->Kill($exitcode);
基本的にはそれが原則です。クロスプラットフォーム ソリューションが必要な場合は、両方のプラットフォームをサポートするモジュールProc::Background on CPAN があります。
use Proc::Background;
my $proc = Proc::Background->new($command, $arg);
# do something ...
$proc->die;