サイトアイコン 知的好奇心

shellで2重起動を抑制する方法

shellで2重起動を抑制する方法をご紹介します。

条件

shellの2重起動抑制処理

シェルに以下のような内容を記述します。

#!/bin/sh

# 二重起動チェック
CMDLINE=$(cat /proc/$$/cmdline | xargs --null)
if [[ $$ -ne $(pgrep -oxf "${CMDLINE}") ]]; then
  echo "既に起動しています!" >&2
  exit 9
fi

簡単な解説

  1. $(cat /proc/$$/cmdline | xargs –null)
    • 起動時のコマンドラインを引数も含めてフルパスで取得し、プロセスIDを取得します。
  2. if [[ $$ -ne $(pgrep -oxf “${CMDLINE}”) ]]; then
    • 「現在のシェルのプロセスID」と「1で取得したプロセスID」が異なる場合、重複実行が行われていると判断します。
    • (シェルを起動したコマンドが同一にも関わらず、プロセスIDが異なるため)

メモ

サンプルプログラム

プログラムの構成

home
└ test
   ├ test.sh
   └ pytest
        └ sample.py

test.sh

動作確認のため、echoで以下の内容を出力します。

#!/bin/bash

# 二重起動チェック
CMDLINE=$(cat /proc/$$/cmdline | xargs --null)

echo ${CMDLINE}
echo $$
echo $(pgrep -oxf "${CMDLINE}")


if [[ $$ -ne $(pgrep -oxf "${CMDLINE}") ]]; then
  echo "既に起動しています!" >&2
  exit 9
fi


cd /home/test/pytest

/usr/bin/python3 sample.py

sample.py

まず「Start!」と表示して、3秒Sleep後に「End!」を表示させるプログラムです。

import time

print("Start!")
time.sleep(3)
print("End!")

シェルのパーミッション設定

シェルに実行権限を設定します。

chmod 754 test.sh

実行結果

コマンドライン引数なしの場合

コンソール画面を2つ開いて、それぞれほぼ同時にtest.shを実行しました。

test@DESKTO:~$ ./test.sh
/bin/bash ./test.sh
364
364
Start!
End!
test@DESKTOP:~$
test@DESKTOP:~$ ./test.sh
/bin/bash ./test.sh
372
364
既に起動しています!
test@DESKTOP-2R7EC85:~$

それぞれのシェルのプロセスIDが異なるため、多重起動と判断されていることがわかります。

コマンドライン引数ありの場合

パラメータを指定しても、同一パラメータであれば多重起動チェックの条件に引っかかります。

test@DESKTOP:~$ ./test.sh aaa bb
/bin/bash ./test.sh aaa bb
384
384
Start!
End!
test@DESKTOP:~$
test@DESKTOP:~$ ./test.sh aaa bb
/bin/bash ./test.sh aaa bb
392
384
既に起動しています!
test@DESKTOP:~$

参考

mk-mode BLOG:Linux – bash スクリプト二重起動チェック!

https://www.mk-mode.com/blog/2016/02/21/linux-bash-check-double-start/#

Qiita:Linuxの権限確認と変更(chmod)(超初心者向け)

https://qiita.com/shisama/items/5f4c4fa768642aad9e06

Qiita:Shell 特殊変数

https://qiita.com/a_yasui/items/ec4f75b300410af8958d

proc – ファイルのフォーマットと規約の説明 – Linux コマンド集 一覧表

https://kazmax.zpp.jp/cmd/p/proc.5.html

きゃまなかのブログ:【Linux】xargs コマンドの使い方がよく分からない

https://techblog.kyamanak.com/entry/2018/02/12/202256

モバイルバージョンを終了