如何获得后台进程的PID?

我从我的shell脚本开始一个后台进程,当我的脚本结束时,我想杀掉这个进程。

如何从我的shell脚本获取这个进程的PID? 据我可以看到variables$! 包含当前脚本的PID,而不是后台进程。

您需要在启动时保存后台进程的PID:

 foo & FOO_PID=$! # do other stuff kill $FOO_PID 

你不能使用工作控制,因为这是一个交互function,并绑定到控制terminal。 一个脚本将不一定有一个terminal连接,所以作业控制不一定是可用的。

您可以使用jobs -l命令来获取特定的作业

 ^Z [1]+ Stopped guard my_mac:workspace r$ jobs -l [1]+ 46841 Suspended: 18 guard 

在这种情况下,46841是PID。

help jobs

-l报告作业的进程组ID和工作目录。

jobs -p是另一个只显示PID的选项。

  • $$是当前脚本的pid
  • $! 是最后一个后台进程的pid

这是一个bash会话的样本抄本( %1是指从jobs看到的后台进程的序号):

 $ echo $$ 3748 $ sleep 100 & [1] 192 $ echo $! 192 $ kill %1 [1]+ Terminated sleep 100 

一个更简单的方法来杀死一个bash脚本的所有subprocess:

 pkill -P $$ 

-P标志与pkillpgrep工作方式相同 – 它获取subprocess,只有pkillsubprocess被杀死,而pgrepsubprocess的PID才会被打印到标准输出。

这是我所做的。 检查出来,希望它可以帮助。

 #!/bin/bash # # So something to show. echo "UNO" > UNO.txt echo "DOS" > DOS.txt # # Initialize Pid List dPidLst="" # # Generate background processes tail -f UNO.txt& dPidLst="$dPidLst $!" tail -f DOS.txt& dPidLst="$dPidLst $!" # # Report process IDs echo PID=$$ echo dPidLst=$dPidLst # # Show process on current shell ps -f # # Start killing background processes from list for dPid in $dPidLst do echo killing $dPid. Process is still there. ps | grep $dPid kill $dPid ps | grep $dPid echo Just ran "'"ps"'" command, $dPid must not show again. done 

然后运行它作为: ./bgkill.sh当然有适当的权限

 root@umsstd22 [P]:~# ./bgkill.sh PID=23757 dPidLst= 23758 23759 UNO DOS UID PID PPID C STIME TTY TIME CMD root 3937 3935 0 11:07 pts/5 00:00:00 -bash root 23757 3937 0 11:55 pts/5 00:00:00 /bin/bash ./bgkill.sh root 23758 23757 0 11:55 pts/5 00:00:00 tail -f UNO.txt root 23759 23757 0 11:55 pts/5 00:00:00 tail -f DOS.txt root 23760 23757 0 11:55 pts/5 00:00:00 ps -f killing 23758. Process is still there. 23758 pts/5 00:00:00 tail ./bgkill.sh: line 24: 23758 Terminated tail -f UNO.txt Just ran 'ps' command, 23758 must not show again. killing 23759. Process is still there. 23759 pts/5 00:00:00 tail ./bgkill.sh: line 24: 23759 Terminated tail -f DOS.txt Just ran 'ps' command, 23759 must not show again. root@umsstd22 [P]:~# ps -f UID PID PPID C STIME TTY TIME CMD root 3937 3935 0 11:07 pts/5 00:00:00 -bash root 24200 3937 0 11:56 pts/5 00:00:00 ps -f 

您可能也可以使用pstree:

 pstree -p user 

这通常给出“用户”的所有进程的文本表示,-p选项给出进程ID。 就我所知,它不依赖于当前shell所拥有的进程。 它也显示叉子。

pgrep可以让你所有的父进程的subprocess。 如前所述$$是当前的脚本PID。 所以,如果你想要一个脚本清理自己,这应该做的伎俩:

 trap 'kill $( pgrep -P $$ | tr "\n" " " )' SIGINT SIGTERM EXIT