bash: сбросить родительское дерево вызовов
Я ищу инструмент рекурсивного Makefile и хочу увидеть полное дерево вызовов, которое привело меня туда, где я нахожусь (включая все параметры и т. Д.). Меня не волнуют другие процессы в системе.
То, что я ищу, по сути pstree -ha
где выводятся только выделенные части (плюс текущий процесс). Заметить, что pstree -ha <PID>
не работает, так как по какой-то причине не показывает родителей родителя (не доходит до init). Я нашел другой ТАК ответ ps -f -g$BINOSPID
, но это показывает братьев и сестер, которые я не хочу.
Чтобы объяснить, что я ищу: я хочу это:
~> sh
sh-4.1$ bash
~> pstree -?? $$
init
`- sshd
`- bash
`- sh
`- bash
`- pstree -?? 1402
Кроме того, как побочный вопрос, pstree -ha
автоматически обрезает список параметров, если он длинный. Есть ли способ избежать этого?
1 ответ
Реализовано в native 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
флаг установлен, если cmdline
не заканчивается разделителем NUL. Это означает, что командная строка была изменена программой, которая была запущена, и больше не содержит своего исходного значения. OpenSSH, в частности, стремится это сделать. В этом случае вместо того, чтобы рассматривать командную строку как список литеральных аргументов, разделенных NUL (и экранировать эти литералы для генерации вывода, который можно было бы скопировать и вставить для генерации той же команды при вызове), мы рассматриваем ее как нечто, что был отформатирован для удобства чтения людьми.
Мы разбираем "${stat_data##*')'}"
из паранойи, чтобы предотвратить приложение, которое содержит буквенные пробелы или )
символы в его исполняемом имени от сбрасывания интерпретации /proc/$pid/stat
,