我有一个调用我的应用程序脚本的脚本 ( 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 为httpd
,30469
并且作为 的子进程的每个进程的httpd
(PPID
父进程 ID)为30469
。的孙子进程httpd
将拥有PPID
其父进程的 ,父进程将拥有PPID
该httpd
进程的 。
我没有发布两者的完整输出,因为它们相当大。以下是每个的输出示例:
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大。这不是您可以依赖的,原因有两个:
- 一旦将允许的最大 PID 分配给进程,就会出现 PID 分配环绕,并且旧的 PID 将开始被重用。当发生回绕时,下一个 PID 将小于而不是大于前一个 PID(之后的新 PID 将跳过仍在运行的进程中用作 PID 的数字)。
一些系统,如 OpenBSD,使用随机 PID 分配:
$ for i in {1..5}; do bash -c 'echo $$'; done 49915 2152 61168 87739 95187
作为旁注,您可以使用$PWD
而不是$(pwd)
获取当前工作目录。