bash:转储父调用树

时间:2018-02-06 16:40:18

标签: bash pstree

我正在寻找一个递归的Makefile,我希望看到完整的调用树让我到达我所在的地方(包括所有参数等)。我不关心系统上的其他进程。

我正在寻找的内容基本上是pstree -ha,它只输出突出显示的部分(加上当前进程)。请注意pstree -ha <PID>不起作用,因为它不会出于某种原因显示父母的父母(它不会一直到初始化)。我找到了另一个SO答案ps -f -g$BINOSPID,但它显示了我不想要的兄弟姐妹。

说明我要找的东西:我想要的是:

~> sh 
sh-4.1$ bash
~> pstree -?? $$

init
`- sshd
   `- bash
      `- sh
         `- bash
            `- pstree -?? 1402

此外,作为附带问题,pstree -ha会自动截断参数列表(如果它为long)。有没有办法避免这种情况?

1 个答案:

答案 0 :(得分:1)

在本机bash中实现,具体取决于具有procfs的操作系统:

#!/usr/bin/env bash

pid=${1:-${BASHPID:-$$}}
while (( pid )); do
   mutated=0
   cmdline=( )
   while IFS= read -r -d '' piece || { [[ $piece ]] && mutated=1; }; do
       cmdline+=( "$piece" )
   done <"/proc/$pid/cmdline"
   printf '%s\t' "$pid"
   if (( mutated )); then
     printf '%s ' "${cmdline[@]}"
   else
     printf '%q ' "${cmdline[@]}"
   fi
   printf '\n'
   stat_data=$(<"/proc/$pid/stat") || break
   read _ ppid _ <<<"${stat_data##*')'}" || break
   [[ $ppid = "$pid" ]] && break
   pid=$ppid
done

如果mutated没有以NUL分隔符结尾,则会设置cmdline标记。这意味着命令行已被运行的程序修改,并且不再包含其原始值。特别是OpenSSH倾向于这样做。在这种情况下,不是将命令行视为NUL分隔的文字参数列表(并且转义那些文字以生成可以被复制并粘贴以在调用时生成相同命令的输出),我们将其视为已被格式化以供人类阅读。

我们正在解析偏执狂"${stat_data##*')'}",以防止包含文字空格或其可执行名称中的)字符的应用程序抛弃/proc/$pid/stat的解释。< / p>