通过脚本名称搜索正在运行的脚本PID

通过脚本名称搜索正在运行的脚本PID

我有以下脚本

hello.sh
--------
while :
do
    echo "hello"
    sleep 20
done

当我运行上面的脚本时,我得到了 2627 作为脚本的 PID

root@localhost ~]# ./hello.sh &
[1] 2627
[root@localhost ~]#

现在,当我在另一个终端中运行 ps 命令时,我没有在输出中获取脚本名称

[root@localhost ~]# ps -ef| grep 262[7]
root      2627  1582  0 19:19 pts/1    00:00:00 -bash
root      3427  2627  0 19:52 pts/1    00:00:00 sleep 20
[root@localhost ~]#

$$ 是我运行脚本的主 shell 的 PID。我知道在脚本中我可以输入 $$ 来获取脚本的 PID,但这不是我的意图。

一旦我在后台运行了长时间运行的脚本,并且假设我意外关闭了终端,那么有没有办法使用脚本名称或任何其他方式来 grep PID?

供参考

[root@localhost ~]# echo $$
2586
[root@localhost ~]# ps -ef| grep 262[7]
root      2627  1582  0 19:19 pts/1    00:00:00 -bash
root      3657  2627  0 20:02 pts/1    00:00:00 sleep 20
[root@localhost ~]# ps -ef| grep bas[h]
root      1517  1513  0 18:43 pts/18   00:00:00 -bash
root      1582  1578  0 18:45 pts/1    00:00:00 -bash
root      2586  2581  0 19:18 pts/54   00:00:00 -bash
root      2627  1582  0 19:19 pts/1    00:00:00 -bash
[root@localhost ~]#

2586 是主 shell 的 PID,在其中,我运行了 hello.sh 脚本。它创建了一个新的 shell 并开始运行其中的命令。这些基本我都知道。这不是一个重复的问题。请查看输出以理解它。

答案1

如果您希望脚本及其名称出现在进程列表中,则应该在脚本中添加适当的 she-bang 行(#! /bin/sh或)。#! /bin/bash

例子:

$ cat foo
sleep 10

$ ./foo &
[4] 4403
$ ps -q 4403
  PID TTY          TIME CMD
 4403 pts/3    00:00:00 bash

$ cat bar
#! /bin/sh
sleep 10

$ ./bar &
[5] 4406
$ ps -q 4406
  PID TTY          TIME CMD
 4406 pts/3    00:00:00 bar

否则,在 Linux 上您仍然可以从目录中找到脚本的名称/proc/PID/fd

$ ./foo &
[2] 5125
$ ls -l /proc/5125/fd
total 0
lrwx------ 1 ahq ahq 64 Oct 22 17:57 0 -> /dev/pts/3
lrwx------ 1 ahq ahq 64 Oct 22 17:57 1 -> /dev/pts/3
lrwx------ 1 ahq ahq 64 Oct 22 17:57 2 -> /dev/pts/3
lr-x------ 1 ahq ahq 64 Oct 22 17:57 254 -> /tmp/foo
lrwx------ 1 ahq ahq 64 Oct 22 17:57 255 -> /dev/pts/3

注意第四行,254fd 指向正在运行的脚本的路径。与其他贝壳相比,bash它会是其他的fd,比如310

也可以使用 进行反向搜索lsof /tmp/foo

答案2

在 Linux 上,您可以:

grep -l hello.sh /proc/*/task/*/comm 2>/dev/null

...它将在命令行中使用“hello.sh”报告您的任何进程(pid 26560,当我运行它时):

/proc/26560/任务/26560/通信

stderr 重定向是为了消除 grep 对当前进程的通信文件 (/proc/self/task/$$/comm) 在 shell 扩展通配符路径和 grep 决定打开它进行读取/grepping 之间消失的抱怨。

如果您运行第二个“hello.sh”,您将得到两个结果,等等:

$ ./hello.sh &
[2] 28328
$ grep -l hello.sh /proc/*/task/*/comm 2>/dev/null
/proc/26560/task/26560/comm
/proc/28328/task/28328/comm

相关内容