web-dev-qa-db-ja.com

プロセスリストの引数と一緒にプロセスをチェックする方法は?

同じスクリプトでいくつかの引数を渡す必要があるスクリプトを作成しました。このスクリプトは、cronを使用して一定時間後に実行されます。スクリプトの複数のインスタンスが実行されていないことを確認するために、スクリプトのプロセスがps -ef | grep -v grep | grep Connection_Manager.shを使用して実行されているかどうかを確認しました

ps -efを使用してチェックを実行するときに、スクリプトの実行プロセスで使用されている引数を確認したい。スクリプトの実行プロセスで使用されている引数を確認するにはどうすればよいですか?

4
Ankit Vashistha

プロセスが既に実行されているかどうかの確認に関しては、あなたがやっていることを少し変更して、代わりに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

次に、awksedなどを使用して、それらの出力を解析します。

sed

$ pgrep -af ./Conn | sed 's/.*Connection_Manager.sh //'
arg1 arg2

awk

$ pgrep -af ./Conn | tr '\000' ' '| awk '{print $4, $5}'
arg1 arg2

これらの2つの方法は頭の中にありませんが、間違いなく効率化できるでしょう。

/ proc /の使用

ただし、引数の数と長さによっては、コマンドラインが長すぎる場合に問題が発生する可能性があります。したがって、おそらく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'

参考文献

15
slm

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
2
Joseph R.

単に実際にロックを使用しないのはなぜですか?

#!/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
1
DopeGhoti

一時ファイルの所有権のセキュリティ問題を含め、これをすでに処理するロックスクリプトを作成しました。 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回の開始時間です。)

1
robbat2