#!/usr/bin/perl -wl use strict; use constant {k_maxLength => 100}; sub loadProcList { my ($procListRef) = @_; my (@F, $pid, $ppid, $output); for (qx(ps -eo pid,ppid,etime,command)) { chomp; @F = split; ($pid, $ppid) = @F[0, 1]; $procListRef->{$pid}->{"pid"} = $pid; $procListRef->{$pid}->{"ppid"} = $ppid; $output = join " ", (@F[0, 2 .. $#F]); $procListRef->{$pid}->{"cmd"} = substr($output, 0, &k_maxLength); push @{$procListRef->{$ppid}->{"cpids"}}, $pid; } } sub printer { my ($procListRef, $pid, $flow, $indent) = @_; my ($ppid, $cpid); # initialize if first call; to be set when recursive call $pid = 0 if !defined($pid); $flow = 0 if !defined($flow); $indent = 0 if !defined($indent); if (defined $procListRef->{$pid}) { if (($flow < 1) && (defined($procListRef->{$pid}->{"ppid"}))) { $ppid = $procListRef->{$pid}->{"ppid"}; # will not be set for top level process (pid = 0) # could have been easier to check if pid=0, but avoiding hardcoding if (exists($procListRef->{$ppid}->{"pid"})) { $indent += printer($procListRef, $ppid, -1, $indent); } } print " " x $indent++ . $procListRef->{$pid}->{"cmd"} if (exists($procListRef->{$pid}->{"cmd"})); # flow > -1 while printing original pid and looking for children if (($flow > -1) && defined($procListRef->{$pid}->{"cpids"})) { for $cpid (@{$procListRef->{$pid}->{"cpids"}}) { printer($procListRef, $cpid, 1, $indent); } } return $indent; } } sub main { my %processHash; loadProcList(\%processHash); printer(\%processHash, $_) foreach (@_?@_:1); } main(@ARGV);