"Еквівалент ps f" для Linux в 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команду у своєму терміналі

У разі відмови команди встановлення, тобто одного коду недостатньо для версії вашої ОС, встановіть Інструменти для розробників командної лінії, виконавши цю команду перед встановленням pstree.

xcode-select --install

1
Як це покращується чи відрізняється від старої прийнятої відповіді apple.stackexchange.com/a/11806/237 ?
користувач151019

Я припускав, що в поточній версії MacOS або Xcode можливі зміни, наприклад, мені довелося встановити Інструменти для розробників командного рядка перед встановленням pstree.
Ethan Stykes

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

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