SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
技術者募集中

コマンドのバックグラウンド処理

sshでログインして普通にコマンド実行すると、以下のような動きになる。

例) php test.php
  1. プロンプトにコマンド入力
  2. 実行
  3. 実行中待つ
  4. 結果が端末に表示される
  5. プロンプトが入力待ちになる

3を待ちたくなくて4の結果が不要な場合は、コマンドの末尾に & をつけることで、バックグラウンドで実行させることができる。

例) php test.php &
  1. プロンプトにコマンド入力(&付き)
  2. 実行
  3. 実行中待たない
  4. プロンプトが入力待ちになる
    (5. 処理が終わった後で端末の変なところに結果が表示されたりはする)

バックグラウンド … 背後で
フォアグラウンド … 前面で

test.php が以下の内容の時、

<?php
sleep(10);
echo 'どうでもよい結果';"

以下のようにフォアグラウンドで実行すると、10秒待たされて、どうでもよい結果が表示される。

$ php test.php
どうでもよい結果
$

以下のようにバックグラウンドで実行すると、即座に「何個目のジョブをプロセスIDいくつで受け付けたか」を表示しつつ、すぐコマンド入力待ちに戻る。

$ php test.php &
[1] 18527
$

以上のように、バックグラウンドで実行する機能がシェルにある。

phpのexecでもこういうことをすることがある。

// 何かの処理
// …

// バックグラウンド処理開始
exec('/usr/local/bin/php nantoka.php > /dev/null &');

// 続きの処理
// …

execのときについてる > /dev/null は何かというと、phpの場合はそうしないとphpが次の処理に行かないから。

注意:プログラムがこの関数で始まる場合、 バックグラウンドで処理を続けさせるには、 プログラムの出力をファイルや別の出力ストリームにリダイレクトする必要があります。 そうしないと、プログラムが実行を終えるまで PHP はハングしてしまいます。

https://www.php.net/manual/ja/function.exec.php

<おまけ>

バックグラウンドで実行中のジョブは確認することができる。

$ php test.php &
$ php test.php &
$ php test.php &
$ php test.php &
$ jobs
[1]   Running                 php test.php &
[2]   Running                 php test.php &
[3]-  Running                 php test.php &
[4]+  Running                 php test.php &

バックグラウンドのジョブはフォアグラウンドに切り替えることができる。

$ fg %3

フォアグラウンドの処理はバックグラウンドに切り替えることができる。

$ php test.php
(あーなかなか終わらいなー)
CTRL+z
[1]+  Stopped                 php test.php
$ bg %1
[1]+ php test.php &
$ jobs
[1]+  Running                 php test.php &

バックグラウンドにいろいろ依頼して、「全部終わったらこれやってね」は一応可能。

$ php shori01.php &
$ php shori02.php &
$ php shori03.php &
$ php shori04.php &
$ wait ; php zenbu_owattara.php

一応可能だけど、プログラムに組み込むと後で保守不能になる可能性はあるので、使いどころは移転作業時のコマンド操作とかプログラム以外の場所かなと思います。

$ ダンプとる &
$ ファイル転送 &
$ wait ; 続きの処理

CPUが遊んでるなら並列処理が有効なことはあるけれど、そうでもないなら1個ずつ順に終わらせるのが速い。なんでもバックグラウンドや並列にしたらいいわけではない。

関連するメモ

コメント