同じスクリプトでいくつかの引数を渡す必要があるスクリプトを作成しました。このスクリプトは、cronを使用して一定時間後に実行されます。スクリプトの複数のインスタンスが実行されていないことを確認するために、スクリプトのプロセスがps -ef | grep -v grep | grep Connection_Manager.sh
を使用して実行されているかどうかを確認しました
ps -ef
を使用してチェックを実行するときに、スクリプトの実行プロセスで使用されている引数を確認したい。スクリプトの実行プロセスで使用されている引数を確認するにはどうすればよいですか?
プロセスが既に実行されているかどうかの確認に関しては、あなたがやっていることを少し変更して、代わりにpgrep
を使用します。
$ pgrep -f Connection_Manager.sh
$ pgrep -f Connection_Manager.sh
16293
-f
スイッチを使用すると、pgrep
を最初の部分だけでなくコマンドライン全体と一致させることができます。
このためには、いくつかの方法があります。 pgrep
の出力からそれらを解析することもできます。追加のスイッチ-a
を追加する必要があります。
$ pgrep -af Conn
17306 /bin/bash ./Connection_Manager.sh arg1 arg2
次に、awk
、sed
などを使用して、それらの出力を解析します。
sed
$ pgrep -af ./Conn | sed 's/.*Connection_Manager.sh //'
arg1 arg2
awk
$ pgrep -af ./Conn | tr '\000' ' '| awk '{print $4, $5}'
arg1 arg2
これらの2つの方法は頭の中にありませんが、間違いなく効率化できるでしょう。
ただし、引数の数と長さによっては、コマンドラインが長すぎる場合に問題が発生する可能性があります。したがって、おそらく2番目の方法を使用して、プロセスのcmdline
ファイルの内容を解析します。すべてのプロセスには、Linuxの/proc
ファイルシステム内に、そのプロセスに関するメタ情報を含む一連のファイルがあります。
$ ls /proc/19146
attr cmdline environ limits mountinfo numa_maps personality stack task
autogroup comm exe loginuid mounts oom_adj root stat timers
auxv coredump_filter fd map_files mountstats oom_score sched statm wchan
cgroup cpuset fdinfo maps net oom_score_adj sessionid status
clear_refs cwd io mem ns pagemap smaps syscall
これらのファイルの1つはファイルcmdline
です。ただし、このファイルの内容には特に注意する必要があります。このファイル内の引数は、NUL文字で区切られています。 cat -v <file>
を使用すると、それらをターミナルウィンドウに表示できます。
$ cat -v cmdline
/bin/bash^@./Connection_Manager.sh^@arg1^@arg2^@
これは、NULの代わりに^@
を使用します。
そのため、コンテンツの解析はさまざまな方法で行うことができます。1つの方法については、xargs -0 ...
を使用して@Joesphの回答で説明しています。もう1つはcat -v
を使用しています。
xargs
$ xargs -0 < cmdline
/bin/bash ./Connection_Manager.sh arg1 arg2
猫
$ cat -v cmdline
/bin/bash^@./Connection_Manager.sh^@arg1^@arg2^@
sed
を使用して、この2番目の方法を少し整理できます。
$ cat -v cmdline | sed 's/\^@/ /g'
proc
ファイルシステムにアクセスできるGNU/Linuxシステムを使用している場合は、次のようにします。
already_running=0
for pid in $(pgrep Connection_Manager.sh);do
if xargs -0 </proc/$pid/cmdline | grep -q ... ;then # match arguments here
already_running=1
break
fi
done
if ! [ $already_running -eq 1 ];then
# run Connection_Manager.sh here
fi
単に実際にロックを使用しないのはなぜですか?
#!/bin/bash
if [[ -f /tmp/$0.lock ]]; then
echo "$0 is locked."
exit 1
else
touch /tmp/$0.lock
trap "rm -f /tmp/$0.lock" EXIT
fi
# The rest of the script
一時ファイルの所有権のセキュリティ問題を含め、これをすでに処理するロックスクリプトを作成しました。 busyboxの下でも動作します。
http://dev.gentoo.org/~robbat2/scripts/pidlock で入手可能な現在のバージョン
/ proc/*/cmdlineを使用して引数を正しくチェックし、古いロックファイルを正しく処理します。 * .gentoo.orgに散在する数百のcronjobに使用されます。
それが機能していることを示す使用例:
$ ( /usr/local/bin/pidlock sleep 5 & ) ; sleep 0.1 ; /usr/local/bin/pidlock sleep 5
Error! 'pidlock-sleep' is running already!
(スリープ0.1は、最初の1回の開始時間です。)