bash: 转储 parent 调用树
bash: Dump a parent call tree
我正在寻找一个递归 Makefile,我希望看到完整的调用树,它让我到达我所在的位置(包括所有参数等)。我不关心系统上的其他进程。
我要找的本质上是pstree -ha
,它只输出突出显示的部分(加上当前进程)。请注意 pstree -ha <PID>
不起作用,因为它出于某种原因不显示 parent 的 parent(它不会一直到 init)。我找到了另一个 SO 答案 ps -f -g$BINOSPID
,但它显示了我不想要的兄弟姐妹。
说出我要找的东西:我想要的是这个:
~> sh
sh-4.1$ bash
~> pstree -?? $$
init
`- sshd
`- bash
`- sh
`- bash
`- pstree -?? 1402
此外,作为附带问题,pstree -ha
会在参数列表过长时自动截断它。有没有办法避免这种情况?
在原生 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
如果 cmdline
不以 NUL 分隔符结尾,则设置 mutated
标志。这意味着命令行已被 运行 的程序修改,不再包含其原始值。 OpenSSH 特别倾向于这样做。在那种情况下,与其将命令行视为以 NUL 分隔的文字参数列表(并转义这些文字以生成可以复制和粘贴以在调用时生成相同命令的输出),不如将其视为已格式化以供人类阅读。
我们正在分析 "${stat_data##*')'}"
脱离偏执狂,以防止在其可执行文件名称中包含文字空格或 )
字符的应用程序摆脱对 /proc/$pid/stat
的解释。
我正在寻找一个递归 Makefile,我希望看到完整的调用树,它让我到达我所在的位置(包括所有参数等)。我不关心系统上的其他进程。
我要找的本质上是pstree -ha
,它只输出突出显示的部分(加上当前进程)。请注意 pstree -ha <PID>
不起作用,因为它出于某种原因不显示 parent 的 parent(它不会一直到 init)。我找到了另一个 SO 答案 ps -f -g$BINOSPID
,但它显示了我不想要的兄弟姐妹。
说出我要找的东西:我想要的是这个:
~> sh
sh-4.1$ bash
~> pstree -?? $$
init
`- sshd
`- bash
`- sh
`- bash
`- pstree -?? 1402
此外,作为附带问题,pstree -ha
会在参数列表过长时自动截断它。有没有办法避免这种情况?
在原生 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
如果 cmdline
不以 NUL 分隔符结尾,则设置 mutated
标志。这意味着命令行已被 运行 的程序修改,不再包含其原始值。 OpenSSH 特别倾向于这样做。在那种情况下,与其将命令行视为以 NUL 分隔的文字参数列表(并转义这些文字以生成可以复制和粘贴以在调用时生成相同命令的输出),不如将其视为已格式化以供人类阅读。
我们正在分析 "${stat_data##*')'}"
脱离偏执狂,以防止在其可执行文件名称中包含文字空格或 )
字符的应用程序摆脱对 /proc/$pid/stat
的解释。