在OSX上相当于Linux的“ ps f”(树视图)?


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

为了澄清,我最感兴趣的是树结构,而不是扩展信息。

Answers:


103

您可以pstree使用Homebrew(我个人的最爱),MacPortsFink安装命令,然后在Mac上获得命令行,进程树视图。

安装Homebrew后,只需运行:

brew install pstree

然后像pstree在命令行中一样使用它。


22

下面我称为perps的小脚本,应该做到这一点;在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

与阿莫斯·夏皮拉(Amos Shapira)的情况类似,我一直在寻找brew自己的东西-需要花费很长时间进行更新,并且没有告诉终端运行的任何信息;所以,对我来说,这个答案是一颗宝石!
27

9

我将Greg Ercolano的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之前通过运行此命令来安装Command Line Developer Tools。

xcode-select --install

1
与以前接受的答案apple.stackexchange.com/a/11806/237相比,这有何改善或不同?
user151019 '17

我以为当前版本的MacOS或Xcode可能会有一些更改,例如,在安装pstree之前,我必须安装命令行开发人员工具。
伊桑·史蒂克斯

没什么变化,您始终需要Xcode命令行工具,如3个软件包管理器的所有安装说明中所述
user151019 2007年

哦!希望我的回答对某人有用。
伊桑·斯蒂克斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.