【问题标题】:How to get child process from parent process如何从父进程获取子进程
【发布时间】:2013-07-18 14:36:31
【问题描述】:

是否可以在 shell 脚本中从父进程 id 获取子进程 id?

我有一个要使用 shell 脚本执行的文件,这会导致一个新进程 process1(父进程)。此 process1 已派生出另一个进程 process2(子进程)。使用脚本,我可以使用以下命令获取 process1 的 pid:

cat /path/of/file/to/be/executed

但我无法获取子进程的 pid。

【问题讨论】:

  • 你说的是哪个子进程和哪个父进程?根据定义,shell 脚本由 shell 进程执行!你为什么要问?请出示你的剧本!
  • 等等...cat 命令如何为您提供 PID?
  • 看来你真的很迷茫!
  • 我第二个@BasileStarynkevitch:请向我们展示您的脚本,或者至少是相关部分。
  • @y_159。在与您类似的程序上使用strace(1)(例如,在pstop)上找出syscalls(2) 所涉及的内容,或从与您类似的现有项目中汲取灵感-githubgitlab

标签: linux shell process child-process


【解决方案1】:

您可以打印父进程调用的所有子进程的 PID:

pstree -p <PARENT_PID> | grep -oP '\(\K[^\)]+'

这会递归打印主进程及其子进程的 pid 列表

【讨论】:

    【解决方案2】:

    您可以通过阅读/proc/<pid>/task/<tid>/children 条目来获取给定父进程<pid> 的所有子进程的pids

    此文件包含第一级子进程的 pid。 对所有子 pid 递归地执行此操作。

    欲了解更多信息,请前往https://lwn.net/Articles/475688/

    【讨论】:

      【解决方案3】:

      我编写了一个脚本来获取父进程的所有子进程 pid。 这是代码。希望它会有所帮助。

      function getcpid() {
          cpids=`pgrep -P $1|xargs`
      #    echo "cpids=$cpids"
          for cpid in $cpids;
          do
              echo "$cpid"
              getcpid $cpid
          done
      }
      
      getcpid $1
      

      【讨论】:

        【解决方案4】:

        对于感兴趣的进程树有超过 2 级的情况(例如 Chromium 产生 4 级深度进程树),pgrep 没有多大用处。正如其他人在上面提到的,procfs 文件包含有关进程的所有信息,只需阅读它们即可。我构建了一个名为 Procpath 的 CLI 工具,它正是这样做的。它读取所有 /proc/N/stat 文件,将内容表示为 JSON 树并将其公开给 JSONPath 查询。

        要获取非 root 进程的所有后代进程的逗号分隔 PID(对于 root,它是 ..stat.pid),它是:

        $ procpath query -d, "..children[?(@.stat.pid == 24243)]..pid"
        24243,24259,24284,24289,24260,24262,24333,24337,24439,24570,24592,24606,...
        

        【讨论】:

          【解决方案5】:

          要获取子进程和线程, pstree -p PID。 它还显示了分层树

          【讨论】:

            【解决方案6】:

            shell进程是$$,因为它是special parameter

            在 Linux 上,proc(5) 文件系统提供了大量有关进程的信息。可能 pgrep(1)(访问/proc)也可能有帮助。

            所以尝试cat /proc/$$/status 来获取shell 进程的状态。

            因此,它的父进程 id 可以通过例如检索到

              parpid=$(awk '/PPid:/{print $2}' /proc/$$/status)
            

            然后在你的脚本中使用$parpid来引用父进程pid(shell的父进程)。

            但我认为你不需要它!

            阅读一些Bash Guide(或小心advanced bash scripting guide,其中有错误)和advanced linux programming

            请注意,一些服务器守护进程(通常需要唯一)将它们的 pid 显式写入/var/run,例如sshd 服务器守护进程正在将其 pid 写入文本文件 /var/run/sshd.pid)。您可能希望将此类功能添加到您自己的类似服务器的程序中(用 C、C++、Ocaml、Go、Rust 或其他一些编译语言编写)。

            【讨论】:

            • 来自 chat.freenode.net 的 graybot 上的 #bash:除非您知道如何过滤掉垃圾,否则应该避免使用臭名昭著的“高级”Bash 脚本指南。它会教你编写错误,而不是脚本。鉴于此,BashGuide 写成:mywiki.wooledge.org/BashGuide;只是想我会提到它!
            【解决方案7】:
            #include<stdio.h>
            #include <sys/types.h>
            #include <unistd.h>
            
            int main()
            {
                // Create a child process     
                int pid = fork();
            
                if (pid > 0)
                {
            
                        int j=getpid();
            
                        printf("in parent process %d\n",j);
                }
                // Note that pid is 0 in child process
                // and negative if fork() fails
                else if (pid == 0)
                {
            
            
            
            
            
                        int i=getppid();
                        printf("Before sleep %d\n",i);
            
                        sleep(5);
                        int k=getppid();
            
                        printf("in child process %d\n",k);
                }
            
                return 0;
            

            }

            【讨论】:

            • 这段代码帮助你从 init() 把一个孤儿进程作为它的子进程
            【解决方案8】:
            ps -axf | grep parent_pid 
            

            上面的命令打印从parent_pid 生成的各个进程,希望对您有所帮助。 +++++++++++++++++++++++++++++++++++++++++++++++

            root@root:~/chk_prgrm/lp#
            
             parent...18685
            
             child... 18686
            
            
            root@root:~/chk_prgrm/lp# ps axf | grep frk
            
             18685 pts/45   R      0:11  |       \_ ./frk
            
             18686 pts/45   R      0:11  |       |   \_ ./frk
            
             18688 pts/45   S+     0:00  |       \_ grep frk
            

            【讨论】:

              【解决方案9】:

              我不确定我是否理解正确,这有帮助吗?

              ps --ppid <pid of the parent>
              

              【讨论】:

              • 带有“linux”标签的问题
              【解决方案10】:

              只需使用:

              pgrep -P $your_process1_pid
              

              【讨论】:

              • 当前进程为shell进程!
              • pgrep -P `pidofproc /path/to/your/process1`
              • pgrep -P 'ppid' 也列出了死进程。如何仅列出活动进程?
              猜你喜欢
              • 2011-07-16
              • 2018-09-09
              • 2017-05-23
              • 2016-01-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多