我想创建一个 bash 别名,它为我提供了从我正在使用的当前 bash 会话到 init 的进程树。
用例是要知道我是否使用了bash
orvi
的:shell
命令。
我用的是MacOS X,听说过pstree
,不过好像只显示children,没有init和当前进程的关系。
我确信通过谷歌搜索,你可以找到如何获取和下载pstree
Mac。但是,你可以做一个穷人的版本,使用ps
and ppid
。
例如
ps -eo ppid,pid,cmd | awk '{p[$1]=p[$1]","$3}END{ for(i in p) print i, p[i]}'
这pstree(1)
通过使用仅显示特定 PID 的树并提供当前进程的 PID($$
在 Bash 中)的选项来支持,该选项的命名在 Werner Almesberger 与 Debian 一起分发的 GPL 许可版本和 Fred 的 BSD 版本之间有所不同Hucht 随 MacOS 一起分发。
在 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>
这是您的 MacOS 别名:
alias psme='pstree -p $$'
我使用的是 Mac OS 10.7 Lion,但我认为这对于其他类 Unix 系统上的类 Bourne shell 来说是相当可移植的。您可能对 ps 参数中的command关键字有疑问。
我将以下代码放在名为 procsup.sh 的文件中,该文件定义了一个 shell 函数,以跟踪进程的父进程直到进程 ID 1。(我经常发现 shell 函数比别名更容易使用。)
procsup()
{
leaf=$$
ps -eo pid,ppid,command | awk -v leaf="$leaf" \
'{parent[$1]=$2;command[$1]=$3;}
function print_ancestry(pid)
{
print pid " (" command[pid] ") child of " parent[pid];
if(pid!=1) print_ancestry(parent[pid])
};
END{\
print_ancestry(leaf)
}'
}
然后我启动了一个 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$
我没有你正在寻找的完整答案,但我有一个想法可能会让你朝着正确的方向前进。命令
declare -A parent
将创建一个关联数组(一个哈希,如果你说 Perl)
您将需要一些命令来为您提供 PID 和 PPID 的名称-值对...我的猜测是,如果您对它进行了足够的折磨,可以使用 mac 的 ps 命令来执行此操作。我将使用上面的“ps -eo”,但您需要填写空白。
然后你可以做这样的事情:
ps -eo pid,ppid | while read pid ppid
do
parent[$pid]=$ppid
echo "pid: $pid ppid: ${parent[$pid]} grandppid: ${parent[${parent[$pid]}]}"
done
我无法让 $parent 的值在我的 while 循环之外持续存在,否则我会创建第二个 for 循环以从 $$ 遍历回 init。我将把它作为练习留给读者。
如果您使用 MacPorts 之类的包管理器,您可以轻松安装 pstree。