No.2ベストアンサー
- 回答日時:
自前のsystemであるmysystemを自作します。
これは、第1引数にタイムアウト時間(秒)を取り、
第2引数以降は、systemを呼び出すときのパラメータの集合をとります。
mysystemの戻り値は
-1:fork失敗(通常あり得ない)
-2:タイムアウト(第1引数で指定された時間内にコマンドが終了しなかった)
255:execエラー(第2引数以降が正しくないのでコマンドとして実行できない)(但し、この仕様は255を終了ステータスで返すコマンドがあるとそのステータスと区別ができない、ということがあるが、まず、これが問題になることはないだろうという前提で作成。対策が無いわけではないが、ソースが複雑になるので、とりあえず、簡易版)
とします。
以下ソースです。
------------------------------------------
#! /usr/bin/perl
$stime = time();
$result = &mysystem(60,@ARGV);
$etime = time();
printf ("result=%d,excuted time=%d\n",$result,$etime-$stime);
#自前のsystem
# P1:タイムアウト時間(単位:秒)
# P2:systemへ渡す文字列
# 戻り値: -1:fork error
# 255:exec error(コマンド文字列不正)
# -2:timeout
# 以外:コマンドの終了ステータス
sub mysystem
{
use POSIX qw( SIGKILL );
my $timeout = shift(@_); #タイムアウト時間
my @cmd = @_; #コマンドリスト
my $pid = fork();
# fork失敗
if (!defined($pid)){
return -1;
}
#子プロセスの場合
if ($pid == 0){
exec(@cmd);
# execが成功すれば戻ってこない
# 下記の文が実行されるのはexec失敗の場合だけ
exit(255);
}
#親プロセスの場合
while($timeout>0){
#my $ret = POSIX::waitpid($pid,&POSIX::WNOHANG);
my $ret = waitpid($pid,&POSIX::WNOHANG);
#プロセス終了時(プロセスの終了ステータスは$?に格納されている)
if ($ret != 0){
#プロセスの終了ステータスを返す
printf("ret=%d,pid=%d,sts=%d\n",$ret,$pid,$?);
return ($?/256);
}
# プロセスが終了していない場合1秒待つ
$timeout--;
sleep(1);
}
#タイムアウト検出時
#子プロセスをKILLする
kill(SIGKILL,$pid);
#殺した子プロセスをみとる(成仏させる)
waitpid($pid,0);
# タイムアウトで終了
return -2;
}
------------------------------------------
上記のスクリプトをsampl.plで保存し、
sampl.pl 実行したいコマンド名
と入力して下さい。
その 実行したいコマンド名を実行し、60秒以内に完了しなければ、
そのコマンドをKILLし、-2で戻ります。(linux(cent-os4.4))で動作確認済みです。
この回答へのお礼
お礼日時:2008/07/23 13:11
希望していたものを遥かに上回る素晴らしいプログラムを書いていただき、ありがとうございます。
使いやすさの点や、戻り値の値など、とても素晴らしいです。
おかげさまで、やりたい処理ができそうです。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) プログラムの起動、利用について、使用期間を設定する方法 3 2023/08/06 21:03
- その他(学校・勉強) この中で間違ってある説明はありますか?詳しい方に教えていただきたいです。 A. 1つのプログラムが複 2 2023/07/14 01:15
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- Windows 10 windows10のクリーンインストールが完了出来ない 2 2022/06/04 13:33
- その他(パソコン・スマホ・電化製品) スマホの動画の録画時間が1回で長いのと発熱による強制終了しにくいスマホ、または録音機を探してます。 2 2022/12/23 08:12
- Windows 7 更新プログラムを入れたら操作出来なくなりました(泣) 1 2023/02/26 11:04
- インターネット広告・アフィリエイト アフェリエイトサイト 作成について 5 2022/05/13 21:31
- Java Java モンスターブリーダー 1 2023/02/05 09:44
- Java Java 南京錠 2 2023/02/04 11:46
- ヤフオク! ヤフオクの取引において「落札者都合」により削除することについて 1 2023/07/16 08:58
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
時間がかかり過ぎたプロセスを...
-
open MAILでの"|"
-
Active Directoryでグループに...
-
例外処理のフローチャートの記...
-
VBAで別モジュールへの変数の受...
-
「デバイスは PRN を初期化でき...
-
本当にPublicな変数(配列で)
-
Excel VBAで、ユーザーフォーム...
-
Excel VBAでリンク切れをチェッ...
-
Excel VBA 『Call』で呼び出す...
-
VBでグローバル変数を宣言するには
-
モジュールとは何ですか
-
vba 標準モジュールインポート...
-
ユーザー定義関数に#NAME?が返...
-
グラフのX,Y座標を取得したい
-
Net::SSH::Perlについて
-
'Range'メソッドは失敗しました
-
VBA モジュールで共通に使う変...
-
"JScript"が見つかりません!
-
Excel VBAで、ユーザーフォー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
時間がかかり過ぎたプロセスを...
-
AIX6でファイルのタイムスタン...
-
LinuxにおいてのPerlのプログラ...
-
実行中のcpan processを終了さ...
-
Perlの処理待ちコマンド
-
open MAILでの"|"
-
Epoch time
-
Perlでexitコードを取得する方法
-
Perlでpopen()的なものを使って...
-
Parallel::ForkManagerについて
-
HELOコマンドが失敗する。
-
perlスクリプト内でシェルコマ...
-
system関数とqx演算子の違いに...
-
gem install houston
-
マルチスレッドとマルチプロセ...
-
標準入出力先の検知
-
MS-DOSでperl実行時にコマンド...
-
macでperl perldocについての...
-
ディスク容量について
-
スクリプトについて教えてくだ...
おすすめ情報