Как отобразить текущее дерево процессов сеанса bash?

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

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

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


person Thaddee Tyl    schedule 21.08.2011    source источник


Ответы (5)


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

eg

ps -eo ppid,pid,cmd | awk '{p[$1]=p[$1]","$3}END{ for(i in p) print i, p[i]}'
person ghostdog74    schedule 21.08.2011
comment
Может быть, я ошибаюсь, но кажется, что pstree, наряду с вашей версией для бедняков, показывает только детей процесса. Обратите внимание, что я не мог правильно использовать вашу версию, так как Mac ps довольно плохой и не поддерживает cmd. Я хотел бы увидеть связь между init и текущим процессом. Есть предположения? - person Thaddee Tyl; 21.08.2011
comment
Кажется, что OS X использует comm вместо cmd в команде ps. - person Thaddee Tyl; 21.08.2011
comment
версия для бедняков просто объединяет все родительские процессы и их дочерние процессы. Это все. - person ghostdog74; 21.08.2011
comment
Версия для бедняков больше не работает на OSX Mountain Lion. - person Koen.; 09.11.2012
comment
Замените cmd на command для некоторых версий команды BSD ps. - person emallove; 25.10.2016

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

  • В 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 $$'
person pneumatics    schedule 01.07.2016
comment
Спасибо! Это именно то, что я искал! И кажется, что это лучший, более прямой ответ, чем принятый - конечно, если у вас есть доступ к pstree. - person Wizek; 05.10.2016
comment
В OSX у меня pstree $Revision: 2.39 $ by Fred Hucht и здесь вариант -s не сработал, а вариант -p сработал: pstree -p $$. - person Alexander Klimetschek; 20.12.2017
comment
спасибо @AlexanderKlimetschek. Я обновил ответ, чтобы показать, что -p требуется для другой версии pstree, распространяемой с MacOS. - person pneumatics; 20.12.2017

Я использовал 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$
person D A Vincent    schedule 11.08.2012

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

person Kai Sternad    schedule 21.08.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. Я оставлю это в качестве упражнения читателю.

person Barton Chittenden    schedule 21.08.2011