如何显示 bash 会话的当前进程树?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7138783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 00:37:46  来源:igfitidea点击:

How to display the current process tree of a bash session?

bashprocessvips

提问by Thaddee Tyl

I would like to create a bash alias that gives me the process tree from the current bash session I am using, up to init.

我想创建一个 bash 别名,它为我提供从我正在使用的当前 bash 会话到 init 的进程树。

The use case is to know whether I have used bashor vi's :shellcommand.

用例是知道我是否使用过bashorvi:shell命令。

I am using MacOS X. I have heard about pstree, but it seems to only show children, not the relationship between init and the current process.

我使用的是 MacOS X。我听说过pstree,但它似乎只显示了 children,而不是 init 和当前进程之间的关系。

采纳答案by ghostdog74

I am sure with a a bit of google search, you can find how to get and download pstreefor the Mac. However, you can do a poor man's version, using psand ppid.

我相信通过一些谷歌搜索,您可以找到如何获取和下载pstreeMac。但是,您可以使用psand做一个穷人的版本ppid

eg

例如

ps -eo ppid,pid,cmd | awk '{p[]=p[]","}END{ for(i in p) print i, p[i]}'

回答by pneumatics

This is supported in pstree(1)by using an option to show the tree only for a particular PID and providing the current process's PID ($$in Bash), The option is named differently between GPL-licensed version by Werner Almesberger distributed with Debian and the BSD version by Fred Hucht distributed with MacOS.

这是pstree(1)通过使用一个选项来显示树只为特定的 PID 并提供当前进程的 PID($$在 Bash 中)来支持的,该选项在 Werner Almesberger 随 Debian 分发的 GPL 许可版本和 Fred 的 BSD 版本之间命名不同Hucht 随 MacOS 分发。

  • On Debian/Ubuntu: pstree -s $$

    init───gnome-terminal───bash───pstree
    

    Summary of -soption:

    -s     Show parent processes of the specified process.
    
  • On MacOS: pstree -p $$

    -+= 00001 root /sbin/launchd
     \-+= 25706philipbranning/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
       \-+= 25716 root login -pfl philipbranning /bin/bash -c exec -la bash /bin/bash
         \-+= 25722 philipbranning -bash
           \-+= 32456 philipbranning pstree -p 25722
             \--- 32457 root ps -axwwo user,pid,ppid,pgid,command
    

    Summary of -poption:

    -p pid    show only branches containing process <pid>
    
  • 在 Debian/Ubuntu 上: pstree -s $$

    init───gnome-terminal───bash───pstree
    

    -s选项摘要:

    -s     Show parent processes of the specified process.
    
  • 在 MacOS 上: pstree -p $$

    -+= 00001 root /sbin/launchd
     \-+= 25706philipbranning/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
       \-+= 25716 root login -pfl philipbranning /bin/bash -c exec -la bash /bin/bash
         \-+= 25722 philipbranning -bash
           \-+= 32456 philipbranning pstree -p 25722
             \--- 32457 root ps -axwwo user,pid,ppid,pgid,command
    

    -p选项摘要:

    -p pid    show only branches containing process <pid>
    

Here's your alias for MacOS:

这是您的 MacOS 别名:

alias psme='pstree -p $$'

回答by D A Vincent

I used Mac OS 10.7 Lion, but I think this will be fairly portable to Bourne-like shells on other Unix-like systems. You may have issues with the commandkeyword in the argument to ps.

我使用了 Mac OS 10.7 Lion,但我认为这对于其他类 Unix 系统上的类 Bourne shell 来说是相当可移植的。您可能对 ps 的参数中的command关键字有疑问。

I put the following code in a file named procsup.sh, which defines a shell function to follow the process's parents up to process ID 1. (I often find shell functions easier to work with than aliases.)

我将以下代码放在一个名为 procsup.sh 的文件中,该文件定义了一个 shell 函数来跟随进程的父进程直到进程 ID 1。(我经常发现 shell 函数比别名更容易使用。)

procsup()
{
     leaf=$$
     ps -eo pid,ppid,command | awk -v leaf="$leaf" \
        '{parent[]=;command[]=;}                                                                                                   
     function print_ancestry(pid)                                                                                                          
     {                                                                                                                                     
         print pid " (" command[pid] ") child of " parent[pid];                                                                            
         if(pid!=1) print_ancestry(parent[pid])                                                                                            
     };                                                                                                                                    
     END{\                                                                                                                                 
         print_ancestry(leaf)                                                                                                              
     }'
}

Then I started a shell and sourced procsup.sh. In real life you would ensure that your new shells would automatically source procsup.sh when started, maybe in your personal .bashrc. First I checked the ancestry from that shell. Then I started vi from that shell. As usual the interaction with vi didn't make it to the transcript until I did :shell. My terminal window looked like this:

然后我启动了一个 shell 并获取了 procsup.sh。在现实生活中,你会确保你的新 shell 在启动时会自动获取 procsup.sh 的源,也许在你的个人 .bashrc 中。首先,我检查了那个壳的血统。然后我从那个 shell 启动 vi。像往常一样,与 vi 的交互直到我做到了才出现在成绩单中:shell。我的终端窗口如下所示:

Mariel:~/Library/Scripts 1j david$
Mariel:~/Library/Scripts 1j david$
Mariel:~/Library/Scripts 1j david$ . procsup.sh
Mariel:~/Library/Scripts 1j david$ procsup
41926 (-bash) child of 41922
41922 (login) child of 41917
41917 (/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal) child of 19281
19281 (/sbin/launchd) child of 1
1 (/sbin/launchd) child of 0
Mariel:~/Library/Scripts 1j david$
Mariel:~/Library/Scripts 1j david$
Mariel:~/Library/Scripts 1j david$ vi

bash-3.2$ # Have just done :shell.
bash-3.2$ . procsup.sh
bash-3.2$ procsup
42325 (/bin/bash) child of 42324
42324 (vi) child of 41926
41926 (-bash) child of 41922
41922 (login) child of 41917
41917 (/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal) child of 19281
19281 (/sbin/launchd) child of 1
1 (/sbin/launchd) child of 0
bash-3.2$
bash-3.2$

回答by Barton Chittenden

I don't have the whole answer that you're looking for, but I've got an idea that might move you in the right direction. The command

我没有你正在寻找的完整答案,但我有一个想法可能会让你朝着正确的方向前进。命令

declare -A parent

will create an associative array (a hash, if you speak Perl)

将创建一个关联数组(一个哈希,如果你说 Perl)

You will need some command that will give you name-value pairs for PID and PPID... my guess is that the mac's ps command can be made to do this if you torture it enough. I'm going to use 'ps -eo' as above, but you'll want to fill in the blanks.

您将需要一些命令来为您提供 PID 和 PPID 的名称-值对...我的猜测是,如果您对其进行足够的折磨,可以使用 mac 的 ps 命令来执行此操作。我将使用上面的“ps -eo”,但您需要填写空白。

Then you can do something like this:

然后你可以做这样的事情:

ps -eo pid,ppid | while read pid ppid
do   
   parent[$pid]=$ppid   
   echo "pid: $pid ppid: ${parent[$pid]} grandppid: ${parent[${parent[$pid]}]}"
done

I was having trouble making the values of $parent persist outside of my while loop, otherwise I would have created a second for loop to traverse from $$ back to init. I'll leave that as an exercise to the reader.

我在使 $parent 的值保持在我的 while 循环之外时遇到了麻烦,否则我会创建第二个 for 循环来从 $$ 遍历回 init。我将把它留给读者作为练习。

回答by Kai Sternad

If you use a package manager like MacPorts you can easily install pstree.

如果您使用像 MacPorts 这样的包管理器,您可以轻松安装 pstree。