在bash中获取主机脚本的PID

在bash中获取主机脚本的PID

我有一个调用我的应用程序脚本的脚本 ( run.sh)。在给定时间,我可能会多次run.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 为httpd30469并且作为 的子进程的每个进程的httpdPPID父进程 ID)为30469。的孙子进程httpd将拥有PPID其父进程的 ,父进程将拥有PPIDhttpd进程的 。

我没有发布两者的完整输出,因为它们相当大。以下是每个的输出示例:

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大。这不是您可以依赖的,原因有两个:

  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)获取当前工作目录。

相关内容