質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

Q&A

解決済

4回答

7681閲覧

シェルスクリプト内から自分自身のプロセス等を監視する方法が知りたい

teityura

総合スコア84

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

0グッド

0クリップ

投稿2018/01/21 09:21

シェルスクリプト内から自分自身のプロセス等を監視する方法が知りたいです。
下記のようなスクリプトをcronで毎分実行するとします。

parent_script.sh

bash

1#!/bin/bash 2 3#以前にcronで呼び出した処理が残っていれば、exitする 4if [ -n $(ps aux |grep 'parent_script.sh' |grep -v "$(date +'%H:%M')") ] then; 5 exit 6fi 7 8if [ hogehoge=1 ] then; 9 bash child_script1.sh 10elif [ hogehoge=2 ] then; 11 bash child_script2.sh 12fi

cronで前に呼び出されたparent_script.shや
child_script1.sh, child_script2.shが実行中であれば、exitするようにしたいのですが、
終了しているはずのプロセスが残っていたりして、上手く監視できません。

psコマンドや他の方法で、
(親の)スクリプト内で(親と子の)スクリプトが実行中か判定する方法はないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

排他制御の機能を使うと良いでしょう。

下記のようなgrand_parent_script.shを作って、これをcronから実行します。

Bash

1#!/bin/sh 2LOCKFILE=/tmp/parent_script.sh.lock 3flock --timeout=0 $LOCKFILE parent_script.sh 4exit 0

ロックファイルが占有できれば、parent_script.shが実行されます。
既に占有されていると、parent_script.shは実行されず、flockがエラー終了します。
占有は、parent_script.shが終了すると自動的に開放されます。

parent_script.shが終了したのにchild_script1.shchild_script2.shが実行を続けるという事があるのであれば、ちょっと面倒ですが、何とかなると思います。

投稿2018/01/21 12:15

otn

総合スコア84531

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2018/01/21 12:46 編集

考え方としてotnさんの方針の方がずっと自然であると思いました。
teityura

2018/03/10 03:07

みなさん、ありがとうございました。
guest

0

(親の)スクリプト内で(親と子の)スクリプトが実行中か判定する方法はないでしょうか。

多分やろうとしていることは次のようなことではないでしょうか?

  • cronで一定時間ごとにスクリプト(parent_script.sh)を実行している
  • 存在チェックしたいのは自分自身のプロセスおよび自分の子供プロセスではない

そうではなくてcronで前回起動した同名のスクリプトがまだ実行中かどうかをチェックしたいのでは?

こう思ったのはご質問に書かれているスクリプトの内容からです。

if [ -n $(ps aux |grep 'parent_script.sh' |grep -v "$(date +'%H:%M')") ] then;

プロセス一覧から'parent_script.sh'を含むプロセスを探そうとしていますよね・・・
これがうまくいかない原因は「自分自身」および「調べるために実行しているgrepコマンド」もgrepにひっかかる点と、日付という曖昧な情報を用いているためと思います。KojiDoiさん回答オプションなどで親プロセスIDを表示できるので、それに基づきプロセスの親子関係を用いた絞り込みを行えばよい気がします。

例えば以下の条件をawkなどで絞り込めば望みのプロセスが選び出せるのではないでしょうか?

  • PPIDが自分の親と同じ

cronデーモンのプロセスがそうなると想定してますが実際に確認したわけではないです。確認してみてください。この条件によりチェックのために起動したgrepコマンドは自動的に除外されます。

  • PIDが自分自身ではない

言うまでもなく今まさに実行しているスクリプト自身を除外するためです。

  • 自分と同じスクリプト名を含む

bash

1$ cat ck.sh 2#!/bin/bash 3echo my pid is $$ 4ps -e -o ppid,pid,command | 5 awk -v ppid=$PPID -v pid=$$ '$1 == ppid && $2 != pid && /ck.sh/' 6sleep 30 7$ chmod +x ck.sh 8$ ./ck.sh & 9[1] 100 10my pid is 100 11$ ./ck.sh & 12[2] 105 13my pid is 105 142 100 /bin/bash ./ck.sh <===これが前回起動したプロセス 15$

最初の起動では該当プロセスがなく、次の起動で直前のスクリプトが実行中であることが検出できていると思います。
(ちなみにわかりやすくするためstdoutは若干整形してます。)

投稿2018/01/21 10:34

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

pidファイルを使用する方法

bash

1#!/bin/bash 2name=`basename $0` 3pidfile="/var/run/${name}.pid" 4 5[[ -f "$pidfile" ]] && exit 0 6 7trap "rm -f -- '$pidfile'" EXIT 8echo $$ > "$pidfile"

追記
子スクリプト対応バージョン

bash

1--- parent_script.sh --- 2#!/bin/bash 3name=`basename $0` 4pidfile="/var/run/${name}.pid" 5 6script_name1=child_script1.sh 7script_name2=child_script2.sh 8pidfile1="/var/run/${script_name1}.pid" 9pidfile2="/var/run/${script_name2}.pid" 10 11[[ -f "$pidfile" -o -f "$pidfile1" -o -f "$pidfile2" ]] && exit 0 12 13trap "rm -f -- '$pidfile'" EXIT 14echo $$ > "$pidfile" 15 16--- child_script1/2.sh --- 17#!/bin/bash 18name=`basename $0` 19pidfile="/var/run/${name}.pid" 20 21[[ -f "$pidfile" ]] && exit 0 22 23trap "rm -f -- '$pidfile'" EXIT 24echo $$ > "$pidfile"

投稿2018/01/21 09:59

編集2018/01/21 10:23
hichon

総合スコア5737

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

psコマンドのバージョンによるようですが、うちの環境では次のようにしてプロセスのIDと親子関係を一覧できます。

ps -e -o ppid,pid,command --forest

投稿2018/01/21 09:32

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問