読者です 読者をやめる 読者になる 読者になる

min117の日記

初期desireもち。趣味Mac,メインFedora,仕事xp。

recpt1のpidを取り出す

PHP

recpt1で実行中の録画のプロセスIDを取得したい(録画停止に使う)。

こんな感じのプロセスがある状態で

f:id:min117:20151107063911p:plain

iPhoneSafariからこうすると

f:id:min117:20151107065728p:plain

こういう結果が返る

f:id:min117:20151107064146p:plain

のを、PHPで作る。

ーーー

まず、プロセスの取り出しを行う。ここまではシェルを使う。awk素晴らしい。

recpt1のプロセスをgrep

$ ps aux | grep recpt1

f:id:min117:20151107064549p:plain

grepコマンド自体が邪魔なので消す。

$ ps aux | grep recpt1 | grep -v grep

f:id:min117:20151107064709p:plain

2列目(PID)と12列目(デバイス名)だけあればいい。awkで切り出す。

$ ps aux | grep recpt1 | grep -v grep | awk '{print $2,$12}'

f:id:min117:20151107065002p:plain

 ーーー

次はhtmlでformを作る。

至ってシンプル。chkPID.htmlから、chkPID.phpを呼び出すようにする。

vim chkPID.html

f:id:min117:20151107070100p:plain

f:id:min117:20151107065728p:plain

ーーー

chkPID.phpを書いていく。

全体はこう。

f:id:min117:20151107070754p:plain

f:id:min117:20151107070830p:plain

f:id:min117:20151107070847p:plain

 ーーー

chkPID.htmlのformからは、「pidchk」という変数名にYESかNOが入ってくる(正確には、配列$_GETのpidchkフィールドか)。

pidchk=YES ならチェック実行する。

f:id:min117:20151107071224p:plain

関数の中で、シェルにプロセスIDを取得させる。

シェルのコマンドを変数 $command に入れる。

f:id:min117:20151107071450p:plain

コマンドの実行結果(へのポインタ)を、変数 $handle に入れる。

$handle = popen($command , "r");

f:id:min117:20151107071903p:plain

うまく $handle に入ったかチェック。入っていなければ処理しない。

f:id:min117:20151107072425p:plain

うまくいくと、例えばこんなバイト列が $command に入ってたとして

7705 --device=/dev/pt3video7

29739 --device=/dev/pt3video6

そこに、ポインタ $handle がつながる。

ーーー

この $handle を、fgets() で読み込む。

読み込みは、バイト列の終わり(feof)になるまで続ける。

while文で、feofにならない間はfgets($handle)し続ける。

f:id:min117:20151107072837p:plain

 ーーー

preg_match()を使って、文字列を切り出す。

$command 文字列

 7705 --device=/dev/pt3video7

とあるうちの、

 PID(プロセス名):7705

 実行デバイス名:video7

を取り出せればよい。

f:id:min117:20151107074913p:plain

preg_match();

preg_match('');

preg_match('//');

preg_match('/正規表現/');

preg_match('/正規表現/' , 文字列$buffer);

preg_match('/正規表現/' , 文字列$buffer , 切り出した文字を入れる配列$m);

okumocchi.jp

最高のサイトがあった。リアルタイムに、配列の格納状況を確認できる。

さっそく確認。

配列m[1]に値が入れば成功。

/(¥s*¥d+)/

 ¥sはスペース。先頭にスペースがあった場合を想定。

  * はそのスペースの「0回」以上の繰り返し(スペースがない場合もある)。

 ¥dは数字。[0-9]と同じ。

  + はその数字の「1回」以上の繰り返し(数字の繰り返し)。

f:id:min117:20151107081936p:plain

/(video.)/

 「video」で始まって、その後に1文字(ドット1つ)ある 

f:id:min117:20151107081948p:plain

ーーー

これらを合わせる。

/(¥s*¥d+).*(video.)/

f:id:min117:20151107081958p:plain

よし。

配列 $m[1] と $m[2] に正規表現キャプチャ(文字列の切り出し)できた。

ーーー

この正規表現PHPソースに書けばいい。

f:id:min117:20151107082309p:plain

これで、

 $m[1] には プロセスIDが入り、

 $m[2] には デバイス名が入る。

これを

 $value = $m[1];

 $key = $m[2];

として変数に入れて、別の配列$ret(←returnのこと)に入れていく。

 $ret = array();

はソースの初めで宣言済み。

 $ret ($key) => $value

 $ret (デバイス名) => プロセスID

として、デバイス名とプロセスIDをひも付けて、関数の返り値として配列$retを返す。

f:id:min117:20151107082903p:plain

ーーー

結果、$command 文字列から配列$retまでの切り出し全体はこうなる。

f:id:min117:20151107083233p:plain

関数はこれで終わり。

ーーー

あとは実行。その関数を呼ぶ。

f:id:min117:20151107083444p:plain

関数の戻り値を、配列変数 $pid に入れる。

f:id:min117:20151107083547p:plain

配列 $pid をwhile文で読み出す。

f:id:min117:20151107083626p:plain

ーーー

テスト実行。

http://myserver/chkPID.html

f:id:min117:20151107083753p:plain

末尾2行で、pid を表示できてた。

これで完成。

ーーー

次回以降で、pidを指定してkillする処理を作る(録画停止)。