Linux '`ps f` (dạng xem cây) tương đương trên OSX?


85

Làm cách nào tôi có thể có được chế độ xem dạng cây như hình dưới đây trên 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

Để làm rõ, tôi chủ yếu quan tâm đến cấu trúc cây, không phải thông tin mở rộng.

Câu trả lời:


103

Bạn có thể cài đặt pstreelệnh bằng Homebrew (yêu thích cá nhân của tôi), MacPorts hoặc Fink và bạn sẽ có được chế độ xem dạng cây, dòng lệnh của các quy trình trên máy Mac của mình.

Với Homebrew được cài đặt, chỉ cần chạy:

brew install pstree

sau đó sử dụng nó như pstreetừ dòng lệnh.


22

Kịch bản perl nhỏ dưới đây mà tôi đã gọi là 'treeps' sẽ thực hiện chính xác điều đó; hoạt động trên linux (Sci Linux 6) + OSX (10.6, 10.9)

Ví dụ đầu ra:

$ ./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

Đây là mã ..

#!/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
Tôi thấy câu trả lời này hữu ích trong trường hợp tôi chưa thể cài đặt Brew (gỡ lỗi các vấn đề về Packer + vmware).
Amos Shapira

1
Đây là một câu trả lời tuyệt vời và cũng là một điểm khởi đầu tuyệt vời, nhưng sẽ hữu ích hơn nếu có một cách để cắt bớt các dòng, khi chúng thực sự rất dài trong OSX và bọc bên trong cửa sổ đầu cuối. Bất cứ ý tưởng về điều này?
Rolf

3
@Rolf treeps | cut -c 1-$COLUMNSsẽ cắt các dòng dài ở chiều rộng của cửa sổ thiết bị đầu cuối hiện tại của bạn. (hoặc một số đơn giản như 100thay vì $COLUMNSbiến)
DouglasDD

tương tự như tình huống của Amos Shapira, thứ mà tôi đang tìm kiếm brewchính nó - mất nhiều thời gian để cập nhật và không cho tôi biết bất cứ điều gì trong thiết bị đầu cuối nơi nó đang chạy; vì vậy, đối với tôi, câu trả lời này là một viên ngọc quý!
Landru27

9

Tôi đã điều chỉnh kịch bản perl của Greg Ercolano thành kịch bản 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, '')

Ví dụ đầu ra:

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

Một tùy chọn khác là htop, có một tùy chọn để hiển thị ở định dạng cây. Bạn có thể nhấn F5tương tác hoặc sử dụng htop -tkhi khởi chạy nó. Để cài đặt:brew install htop

nhập mô tả hình ảnh ở đây

Nguồn: ServerFault


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

Dán cái này vào terminal của bạn để cài đặt Homebrew, cái này sẽ cho phép bạn cài đặt pstree.

Sau đó cài đặt pstree bằng lệnh này

brew install pstree

Bây giờ bạn có thể sử dụng pstreelệnh trong thiết bị đầu cuối của bạn

Trong trường hợp lệnh cài đặt thất bại, tức là.Xcode không đủ trên phiên bản HĐH của bạn, hãy cài đặt Công cụ dành cho nhà phát triển dòng lệnh bằng cách chạy lệnh này trước khi cài đặt pstree.

xcode-select --install

1
Làm thế nào để cải thiện hoặc khác với câu trả lời cũ được chấp nhận apple.stackexchange.com/a/11806/237 ?
dùng151019

Tôi giả định rằng có thể có một số thay đổi trong phiên bản hiện tại của MacOS hoặc Xcode, ví dụ tôi phải cài đặt Công cụ dành cho nhà phát triển dòng lệnh trước khi cài đặt pstree.
Ethan Stykes

Không có thay đổi, bạn luôn cần các công cụ dòng lệnh Xcode như được đề cập trong tất cả các hướng dẫn cài đặt cho 3 trình quản lý gói
user151019

Oh!, Hy vọng câu trả lời của tôi hữu ích cho ai đó bằng cách nào đó.
Ethan Stykes
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.