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,

Другие вопросы по тегам