Linux '`ps f` (arborescence) équivalent sur OSX?

85

Comment puis-je obtenir une vue arborescente comme celle ci-dessous sous 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

Pour clarifier, je m'intéresse surtout à la structure arborescente, pas aux informations étendues.

vartec
la source

Réponses:

103

Vous pouvez installer la pstreecommande à l'aide de Homebrew (mon favori personnel), de MacPorts ou de Fink . Vous obtiendrez une vue en ligne de commande et une arborescence des processus sur votre Mac.

Avec Homebrew installé, lancez simplement:

brew install pstree

puis utilisez-le comme en pstreeligne de commande.

Ian C.
la source
22

Le petit script perl ci-dessous que j'ai appelé "les treeps" devrait faire exactement cela; fonctionne sur linux (Sci Linux 6) + OSX (10.6, 10.9)

Exemple de sortie:

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

Voici le code ..

#!/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
la source
1
J'ai trouvé cette réponse utile dans une situation où je ne pouvais pas encore installer Brew (problèmes de débogage de Packer + vmware).
Amos Shapira
1
C’est une excellente réponse et un excellent point de départ également, mais il serait plus utile s’il existe un moyen de tronquer les lignes, car elles prennent très, très longtemps sous OSX et s’enroulent dans la fenêtre du terminal. Des idées à ce sujet?
Rolf
3
@Rolf treeps | cut -c 1-$COLUMNScoupera les longues lignes à la largeur de votre fenêtre de terminal actuelle. (ou un simple nombre comme 100au lieu de la $COLUMNSvariable)
DouglasDD
Comme dans la situation d’Amos Shapira, ce que j’ai cherché c’est cela brewmême: il faut beaucoup de temps pour mettre à jour et ne rien me dire dans le terminal où il tourne; alors, pour moi, cette réponse est un joyau!
landru27
9

J'ai adapté le script Perl de Greg Ercolano au 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, '')

Exemple de sortie:

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)
...
Miaou
la source
2

Une autre option est htop, qui a une option pour afficher sous forme d'arborescence. Vous pouvez appuyer de manière F5interactive ou utiliser htop -tlors du lancement. À installer:brew install htop

entrez la description de l'image ici

Source: ServerFault

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

Collez-le dans votre terminal pour installer Homebrew qui vous permettra d’installer pstree.

Puis installez pstree en utilisant cette commande

brew install pstree

Maintenant, vous pouvez utiliser la pstreecommande dans votre terminal

Si la commande d'installation échoue, c'est-à-dire qu'un code X seul ne suffit pas pour la version de votre système d'exploitation, installez Command Line Developer Tools en exécutant cette commande avant d'installer pstree.

xcode-select --install
Ethan Stykes
la source
1
En quoi cela améliore-t-il ou diffère-t-il de l'ancienne réponse acceptée apple.stackexchange.com/a/11806/237 ?
user151019
J'ai supposé qu'il pourrait y avoir des changements dans la version actuelle de MacOS ou Xcode, par exemple, je devais installer Command Line Developer Tools avant d'installer pstree.
Ethan Stykes
Pas de changement, vous avez toujours eu besoin des outils de ligne de commande Xcode, comme indiqué dans toutes les instructions d'installation pour les 3 gestionnaires de paquets
user151019,
Oh !, espérons que ma réponse soit utile à quelqu'un en quelque sorte.
Ethan Stykes