Linux '`ps f` (древовидное представление) эквивалентно OSX?


85

Как я могу получить древовидное представление, как показано ниже на OSX?

vartec@some_server:~$ ps xf
PID TTY      STAT   TIME COMMAND
11519 ?        S      0:00 sshd: vartec@pts/0
11520 pts/0    Ss     0:00  \_ -bash
11528 pts/0    R+     0:00      \_ ps xf

Чтобы уточнить, меня больше всего интересует древовидная структура, а не расширенная информация.

Ответы:


103

Вы можете установить pstreeкоманду, используя Homebrew (мой личный фаворит), MacPorts или Fink, и вы получите командную строку, древовидное представление процессов на вашем Mac.

С установленным Homebrew просто запустите:

brew install pstree

затем используйте его как pstreeиз командной строки.


22

Ниже приведен небольшой Perl-скрипт, который я назвал «treeps», который должен делать именно это; работает на Linux (Sci Linux 6) + OSX (10.6, 10.9)

Пример вывода:

$ ./treeps
    |_ 1        /sbin/launchd
        |_ 10       /usr/libexec/kextd
        |_ 11       /usr/sbin/DirectoryService
        |_ 12       /usr/sbin/notifyd
        |_ 118      /usr/sbin/coreaudiod
        |_ 123      /sbin/launchd
    [..]
           |_ 157      /Library/Printers/hp/hpio/HP Device [..]
           |_ 172      /Applications/Utilities/Terminal.app [..]
              |_ 174      login -pf acct
                 |_ 175      -tcsh
                    |_ 38571    su - erco
                       |_ 38574    -tcsh

Вот код

#!/usr/bin/perl
# treeps -- show ps(1) as process hierarchy -- v1.0 erco@seriss.com 07/08/14
my %p; # Global array of pid info
sub PrintLineage($$) {    # Print proc lineage
  my ($pid, $indent) = @_;
  printf("%s |_ %-8d %s\n", $indent, $pid, $p{$pid}{cmd}); # print
  foreach my $kpid (sort {$a<=>$b} @{ $p{$pid}{kids} } ) {  # loop thru kids
    PrintLineage($kpid, "   $indent");                       # Recurse into kids
  }
}
# MAIN
open(FD, "ps axo ppid,pid,command|");
while ( <FD> ) { # Read lines of output
  my ($ppid,$pid,$cmd) = ( $_ =~ m/(\S+)\s+(\S+)\s(.*)/ );  # parse ps(1) lines
  $p{$pid}{cmd} = $cmd;
  # $p{$pid}{kids} = (); <- this line is not needed and can cause incorrect output
  push(@{ $p{$ppid}{kids} }, $pid); # Add our pid to parent's kid
}
PrintLineage(($ARGV[0]) ? $ARGV[0] : 1, "");     # recurse to print lineage starting with specified PID or PID 1.

1
Я нашел этот ответ полезным в ситуации, когда я еще не мог установить Brew (отладка проблем Packer + vmware).
Амос Шапира

1
Это отличный ответ и отличная отправная точка, но было бы более полезно, если бы существовал способ обрезать строки, поскольку они действительно очень длинные в OSX и переносятся в окно терминала. Есть идеи по этому поводу?
Рольф

3
@Rolf обрежет treeps | cut -c 1-$COLUMNSдлинные строки по ширине вашего текущего окна терминала. (или просто как число 100вместо $COLUMNSпеременной)
DouglasDD

как и в случае с Амосом Шапирой, я сам искал это: brewон долго обновлялся и ничего не говорил мне в терминале, где он работает; так что для меня этот ответ - драгоценный камень!
landru27

9

Я адаптировал Perl-скрипт Грега Эрколано к Python-скрипту.

#!/usr/bin/env python2.7

import subprocess as subp
import os.path
import sys
import re
from collections import defaultdict

def psaxo():
    cmd = ['ps', 'axo', 'ppid,pid,comm']
    proc = subp.Popen(cmd, stdout=subp.PIPE)
    proc.stdout.readline()
    for line in proc.stdout:
        yield line.rstrip().split(None,2)

def hieraPrint(pidpool, pid, prefix=''):
    if os.path.exists(pidpool[pid]['cmd']):
        pname = os.path.basename(pidpool[pid]['cmd'])
    else:
        pname = pidpool[pid]['cmd']
    ppid = pidpool[pid]['ppid']
    pppid = pidpool[ppid]['ppid']
    try:
        if pidpool[pppid]['children'][-1] == ppid:
            prefix = re.sub(r'^(\s+\|.+)[\|`](\s+\|- )$', '\g<1> \g<2>', prefix)
    except IndexError:
        pass
    try:
        if pidpool[ppid]['children'][-1] == pid:
            prefix = re.sub(r'\|- $', '`- ', prefix)
    except IndexError:
        pass
    sys.stdout.write('{0}{1}({2}){3}'.format(prefix,pname,pid, os.linesep))
    if len(pidpool[pid]['children']):
        prefix = prefix.replace('-', ' ')
        for idx,spid in enumerate(pidpool[pid]['children']):
            hieraPrint(pidpool, spid, prefix+' |- ')

if __name__ == '__main__':
    pidpool = defaultdict(lambda:{"cmd":"", "children":[], 'ppid':None})
    for ppid,pid,command in psaxo():
        ppid = int(ppid)
        pid  = int(pid)
        pidpool[pid]["cmd"] = command
        pidpool[pid]['ppid'] = ppid
        pidpool[ppid]['children'].append(pid)

    hieraPrint(pidpool, 1, '')

Пример вывода:

launchd(1)
 |- syslogd(38)
 |- UserEventAgent(39)
 |- kextd(41)
 |- fseventsd(42)
 |- thermald(44)
 |- appleeventsd(46)
...
 |- iTerm(2879)
 |   |- login(2883)
 |   |   `- -bash(2884)
 |   |       `- Python(17781)
 |   |           `- ps(17782)
 |   |- login(7091)
 |   |   `- -bash(7092)
 |   |       `- ssh(7107)
 |   `- login(7448)
 |       `- -bash(7449)
 |           `- bash(9040)
 |               `- python(9041)
 |- installd(2909)
 |- DataDetectorsDynamicData(3867)
 |- netbiosd(3990)
 |- firefox(5026)
...

2

Другой вариант htop, который имеет возможность отображать в древовидном формате. Вы можете нажать в F5интерактивном режиме, или использовать htop -tпри запуске. Установить:brew install htop

введите описание изображения здесь

Источник: ServerFault


1
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Вставьте это в свой терминал, чтобы установить Homebrew, который позволит вам установить pstree.

Затем установите pstree с помощью этой команды

brew install pstree

Теперь вы можете использовать pstreeкоманду в вашем терминале

В случае сбоя команды install, т. Е. Одного только XCode недостаточно для версии вашей ОС, установите Инструменты разработчика командной строки, выполнив эту команду перед установкой pstree.

xcode-select --install

1
Как это улучшится или будет отличаться от старого принятого ответа apple.stackexchange.com/a/11806/237 ?
user151019

Я предположил, что могут быть некоторые изменения в текущей версии MacOS или XCode, например, мне пришлось установить инструменты командной строки для разработчиков перед установкой pstree.
Итан Стайкс

Без изменений, вам всегда были нужны инструменты командной строки Xcode, как упоминалось во всех инструкциях по установке для 3 менеджеров пакетов
user151019

О, надеюсь, мой ответ кому-нибудь пригодится.
Итан Стайкс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.