Как отобразить текущее дерево процессов сеанса Bash? - PullRequest
6 голосов
/ 21 августа 2011

Я хотел бы создать псевдоним bash, который дает мне дерево процессов из текущего сеанса bash, который я использую, вплоть до init.

Вариант использования: узнать, использовал ли я команду bash или vi :shell.

Я использую MacOS X. Я слышал о pstree, но кажется, что он показывает только детей, а не связь между init и текущим процессом.

Ответы [ 5 ]

5 голосов
/ 21 августа 2011

Я уверен, что немного поискав в Google, вы можете найти, как получить и загрузить pstree для Mac.Тем не менее, вы можете сделать версию для бедного человека, используя ps и ppid.

например

ps -eo ppid,pid,cmd | awk '{p[$1]=p[$1]","$3}END{ for(i in p) print i, p[i]}'
3 голосов
/ 02 июля 2016

Это поддерживается в pstree(1) благодаря использованию опции для отображения дерева только для определенного PID и предоставлению PID текущего процесса ($$ в Bash). Эта опция по-разному называется в версии с лицензией GPL Вернером Альмесбергером распространяется вместе с Debian и версией BSD Фредом Хухтом (Macred).

  • В 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 $$'
2 голосов
/ 11 августа 2012

Я использовал Mac OS 10.7 Lion, но я думаю, что это будет довольно переносимо для Bourne-подобных оболочек в других Unix-подобных системах. У вас могут возникнуть проблемы с ключевым словом command в аргументе ps.

Я поместил следующий код в файл с именем procsup.sh, который определяет функцию оболочки, которая следует за родителями процесса до идентификатора процесса 1. (Я часто нахожу, что с функциями оболочки легче работать, чем с псевдонимами).

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)                                                                                                              
     }'
}

Затем я запустил оболочку и загрузил procsup.sh. В реальной жизни вы гарантируете, что ваши новые оболочки будут автоматически загружать procsup.sh при запуске, возможно, в ваш личный .bashrc. Сначала я проверил родословную этой оболочки. Затем я запустил 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$
1 голос
/ 21 августа 2011

У меня нет полного ответа, который вы ищете, но у меня есть идея, которая может направить вас в правильном направлении.Команда

declare -A parent

создаст ассоциативный массив (хеш, если вы говорите на Perl)

Вам понадобится какая-нибудь команда, которая даст вам пары имя-значение для PID и PPID ..Я полагаю, что для этого можно использовать команду ps для Mac, если вы пытаете ее достаточно.Я собираюсь использовать '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.Я оставлю это в качестве упражнения для читателя.

1 голос
/ 21 августа 2011

Если вы используете менеджер пакетов, такой как MacPorts, вы можете легко установить pstree.

...