¿Linux '' ps f` (vista de árbol) equivalente en OSX?

85

¿Cómo puedo obtener una vista de árbol como la siguiente en 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

Para aclarar, estoy principalmente interesado en la estructura de árbol, no en la información extendida.

vartec
fuente

Respuestas:

103

Puede instalar el pstreecomando usando Homebrew (mi favorito personal), MacPorts o Fink y obtendrá una vista de árbol de línea de comandos de procesos en su Mac.

Con Homebrew instalado, simplemente ejecute:

brew install pstree

luego úsalo como pstreedesde la línea de comandos.

Ian C.
fuente
22

El siguiente script de perl pequeño que he llamado 'treeps' que debería hacer exactamente eso; funciona en linux (Sci Linux 6) + OSX (10.6, 10.9)

Salida de ejemplo:

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

Aquí está el código ...

#!/usr/bin/perl
# treeps -- show ps(1) as process hierarchy -- v1.0 [email protected] 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.
Greg Ercolano
fuente
1
Encontré esta respuesta útil en una situación en la que aún no podía instalar Brew (depuración de problemas de Packer + vmware).
Amos Shapira
1
Esta es una gran respuesta y un excelente punto de partida también, pero sería más útil si hubiera una forma de truncar las líneas, ya que se vuelven realmente muy largas en OSX y se ajustan dentro de la ventana de terminal. ¿Alguna idea sobre esto?
Rolf
3
@Rolf treeps | cut -c 1-$COLUMNScortará las largas líneas en el ancho de su ventana de terminal actual. (o un número simple como en 100lugar de la $COLUMNSvariable)
DouglasDD
similar a la situación de Amos Shapira, lo que me hace buscar esto es en brewsí mismo: me lleva mucho tiempo actualizarlo y no me dice nada en el terminal donde se está ejecutando; entonces, para mí, ¡esta respuesta es una joya!
landru27
9

Adapte el script perl de Greg Ercolano al script 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, '')

Salida de ejemplo:

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)
...
maullar
fuente
2

Otra opción es htop, que tiene una opción para mostrar en formato de árbol. Puede presionar de forma F5interactiva o usar htop -tal iniciarlo. Instalar:brew install htop

ingrese la descripción de la imagen aquí

Fuente: ServerFault

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

Pegue esto en su terminal para instalar Homebrew que le permitirá instalar pstree.

Luego instale pstree usando este comando

brew install pstree

Ahora puedes usar el pstreecomando en tu terminal

En caso de que falle el comando de instalación, es decir, Xcode por sí solo no es suficiente en la versión de su sistema operativo, instale Command Line Developer Tools ejecutando este comando antes de instalar pstree.

xcode-select --install
Ethan Stykes
fuente
1
¿Cómo mejora esto o se diferencia de la respuesta anterior aceptada apple.stackexchange.com/a/11806/237 ?
user151019
Supuse que podría haber algunos cambios en la versión actual de MacOS o Xcode, por ejemplo, tuve que instalar Command Line Developer Tools antes de instalar pstree.
Ethan Stykes
No, sin cambios, siempre necesitó las herramientas de línea de comandos de Xcode como se menciona en todas las instrucciones de instalación para los 3 administradores de paquetes
usuario151019
¡Oh !, espero que mi respuesta sea útil para alguien de alguna manera.
Ethan Stykes