BashからホストスクリプトのPIDを取得する

BashからホストスクリプトのPIDを取得する

私のアプリケーションスクリプトを呼び出すscript()がありますrun.shrun.sh与えられた時間にこれを複数回実行できます。

run.shスクリプトの一般的な形式は次のとおりです。

#!/bin/bash
# Running DALTON JOB: Helix
dir=$(pwd)
    echo "-----------------------------------------------"
   export DALTON_TMPDIR=/mnt/raid0/scratch
    export OMP_NUM_THREADS=6
    source /opt/intel/compilers_and_libraries_2017.0.098/linux/bin/compilervars.sh intel64
    source /opt/intel/mkl/bin/mklvars.sh intel64
    echo "//-------process started----------------------------//"

./application.sh  -mb 14550 input.mol output.out

echo "//-------process finished----------------------------//"

application.shスクリプト内でPIDを取得できますかrun.sh? ($$スクリプト自体のPIDを提供することがわかりました。)

また、アプリケーションのPIDは常に親スクリプトよりも数値的に大きいことがわかりましたが、これは偶然の一致かもしれません。

答え1

実行中のPIDを表示するには、明示的にapplication.shバックグラウンドに置き、PIDをキャプチャしてから終了するのを待つことをお勧めします。

# ...
./application.sh  -mb 14550 input.mol output.out &
app_pid=$!
echo "The application pid is: $app_pid"
wait "$app_pid"
# ...

答え2

pstree -p合計や追加のps axjf構文解析などの組み合わせが必要になる可能性があると思います。

PIDはhttpd、各プロセスの(親プロセスID)は30469子プロセスです。孫プロセスは親プロセスを所有し、親プロセスはそのプロセスを所有します。httpdPPID30469httpdPPIDPPIDhttpd

どちらもかなり大きいため、出力全体を公開しません。以下は各出力の例です。

user@host$ ps -axjf
PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
1     30469 30469 30469 ?           -1 Ss       0   0:46 /usr/sbin/httpd
30469 22410 22410 22410 ?           -1 Ssl      0   0:00  \_ PassengerWatchdog
22410 22413 22413 22410 ?           -1 Sl       0  23:06  |   \_ PassengerHelperAgent
22410 22418 22418 22410 ?           -1 Sl      99   0:01  |   \_ PassengerLoggingAgent
30469 22442 30469 30469 ?           -1 Sl      48   7:55  \_ (wsgi:pulp)
30469 22443 30469 30469 ?           -1 S       48   1:48  \_ /usr/sbin/httpd
30469 22445 30469 30469 ?           -1 S       48   1:55  \_ /usr/sbin/httpd
30469 22447 30469 30469 ?           -1 S       48   1:54  \_ /usr/sbin/httpd

user@host$ pstree -p
 ├─httpd(30469)─┬─PassengerWatchd(22410)─┬─PassengerHelper(22413)─┬─{PassengerHelpe}(22415)
        │              │                        │                        ├─{PassengerHelpe}(22416)
        │              │                        │                        ├─{PassengerHelpe}(22417)
        │              │                        │                        ├─{PassengerHelpe}(22420)
        │              │                        │                        ├─{PassengerHelpe}(22422)
        │              │                        │                        ├─{PassengerHelpe}(22423)
        │              │                        │                        ├─{PassengerHelpe}(29342)

親プロセスツリーがわかっている場合は実行できますpstree -p <pid>

答え3

ユーティリティのプロセスIDを保存するには、非同期プロセスで始まり、そのPIDを変数に保存するか、$!直接使用します(最も最近起動されたバックグラウンドプロセスのPID)。

#!/bin/bash

export DALTON_TMPDIR=/mnt/raid0/scratch
export OMP_NUM_THREADS=6
source /opt/intel/compilers_and_libraries_2017.0.098/linux/bin/compilervars.sh intel64
source /opt/intel/mkl/bin/mklvars.sh intel64

printf 'Started at "%s"\n' "$(date)"

SECONDS=0
./application.sh -mb 14550 input.mol output.out &

app_pid="$!"

printf 'Application PID is %d\n' "$app_pid"

wait "$app_pid"

printf 'Ended at "%s"\n' "$(date)"
printf 'Run time was approximately %d minutes (%d seconds)\n' "$(( SECONDS/60 ))" "$SECONDS"

アプリケーションのPIDはです$app_pid


新しいプロセスのPIDが常に前のプロセスのPIDよりも大きいことがわかりました。これは、次の2つの理由で信頼できるものではありません。

  1. 許可された最大PIDがプロセスに割り当てられると、PID割り当てラップアラウンドが発生し、古いPIDが再利用され始めます。ラップアラウンドが発生すると、次のPIDは前のPIDよりも小さくなります。それ以降の新しいPIDは、まだ実行中のプロセスでPIDとして使用される番号をスキップします。
  2. OpenBSD などの一部のシステムでは、ランダムな PID 割り当てを使用します。

    $ for i in {1..5}; do bash -c 'echo $$'; done
    49915
    2152
    61168
    87739
    95187
    

ちなみに、代わりにを使用して現在の作業ディレクトリをインポートでき$PWDます$(pwd)

関連情報