Example script: ptree-ksh.ksh


   1: #!/bin/ksh
   2: #
   3: ## sh code translated to ksh, with some additional optimizations
   4: ## RB Oct 2002
   5: #---------------------------------------------------------------
   6: 
   7: #
   8: # Copyright 1995, by Hewlett-Packard Company
   9: #
  10: # The code in this file is from the book "Shell Programming
  11: # Examples" by Bruce Blinn, published by Prentice Hall.
  12: # This file may be copied free of charge for personal,
  13: # non-commercial use provided that this notice appears in
  14: # all copies of the file.  There is no warranty, either
  15: # expressed or implied, supplied with this code.
  16: #
  17: # NAME
  18: #    ptree - print a process tree
  19: #
  20: # SYNOPSIS
  21: #    ptree [-n] [pid]
  22: #    ptree [-n] [pid] [level] [datafile]
  23: #
  24: # DESCRIPTION
  25: #    This command will print the process tree for the
  26: #    process identified by pid.  When called by the user,
  27: #    only the first format shown should be used.  If the
  28: #    process ID (pid) is not passed, process 1 is assumed.
  29: #
  30: #    The second format of this command is only used when
  31: #    this command calls itself recursively to print the next
  32: #    level of the process tree.
  33: #
  34: #    -n   Do not recurse
  35: #
  36: # RETURN VALUE
  37: #    0    Successful completion
  38: #    1    Usage error
  39: #
  40: ############################################################
  41: ## Put our own directory in the PATH, since we use recursion
  42: ## ksh lets us avoid using `dirname`
  43: ## Also, make sure /usr/bin/ps is ahead of any other version of ps (/usr/ucb etc.)
  44: PATH=/usr/bin:$PATH:${0%/*}
  45: 
  46: ## Don't even import this function if we've already used it
  47: if [[ -z "$SYSTEM" ]]; then
  48: . SystemType.sh
  49: fi
  50: 
  51: integer INDENT LEVEL
  52: 
  53: CMDNAME=${0##*/}
  54: USAGE="Usage: $CMDNAME [-n] [pid]"
  55: RECURSIVE=TRUE           # List processes recursively
  56: PROCESS=                 # PID of the starting process
  57: LEVEL=                   # Indentation level (num parents)
  58: DATAFILE=                # Reformatted output from ps
  59: PS_OPTS=                 # Options for the ps command
  60: OLD_IFS=$IFS             # Original value of IFS variable
  61: 
  62: ## Setting SYSTEM is expensive - don't do it more than once 
  63: SYSTEM=${SYSTEM:=`SystemType`}; export SYSTEM
  64: # SYSTEM=`SystemType`      # String identifying the system
  65: 
  66: #
  67: # Temporaries
  68: #
  69: PID=                     # Process ID
  70: PPID=                    # Process ID of the parent process
  71: OWNER=                   # Owner of the process
  72: NAME=                    # Name of the process
  73: LINE=                    # Line from the data file
  74: OUTLINE=                 # Line of output
  75: INDENT=                  # Column number where line begins
  76: 
  77: trap 'rm -f /tmp/*.$$; exit 1' 1 2 3 15
  78: 
  79: FillLine() {
  80:      #
  81:      # SYNOPSIS
  82:      #    FillLine line column
  83:      #
  84:      integer _COLUMN _LEN
  85:      _LINE="$1"
  86:      _COLUMN=$2
  87:      ## Using ksh lets us do this arithmetic internally
  88:      ## otherwise `expr` is needed potentially thousands of times
  89:      _LEN=${#_LINE}
  90:      while [[ $_LEN -lt $_COLUMN ]]
  91:      do
  92:           _LINE="$_LINE "
  93:           _COLUMN=$(($_COLUMN - 1))
  94:      done
  95: 
  96:      print "$_LINE"
  97: }
  98: 
  99: while :
 100: do
 101:      case $1 in
 102:           -n)  RECURSIVE=FALSE
 103:                shift
 104:                ;;
 105:           --)  shift
 106:                break
 107:                ;;
 108:           -*)  print "$USAGE" 1>&2
 109:                exit 1
 110:                ;;
 111:           *)   break
 112:                ;;
 113:      esac
 114: done
 115: 
 116: #
 117: # Make sure the number of parameters is reasonable.
 118: #
 119: if [[ $# -eq 0 ]] then
 120:      PROCESS=1
 121:      LEVEL=0
 122:      DATAFILE=/tmp/ptree.$$
 123: elif [[ $# -eq 1 ]]; then
 124:      PROCESS=$1
 125:      LEVEL=0
 126:      DATAFILE=/tmp/ptree.$$
 127: elif [[ $# -eq 3 ]]; then
 128:      PROCESS=$1
 129:      LEVEL=$2
 130:      DATAFILE=$3
 131: else
 132:      print "$USAGE" 1>&2
 133:      exit 1
 134: fi
 135: 
 136: if [[ "$LEVEL" = 0 ]]; then
 137:      #
 138:      # Determine which options to use with the ps command.
 139:      #
 140:      case $SYSTEM in
 141:           SUNBSD | ULTRIX )   PS_OPTS="-auwx"     ;;
 142:           * )                 PS_OPTS="-ef"       ;;
 143:      esac
 144: 
 145:      #
 146:      # Build the data file.
 147:      #
 148:      rm -f $DATAFILE
 149: 
 150:      ## Fragile programming! - depends closely on the exact output of ps
 151:      case $SYSTEM in
 152:      SGI62 )                       COL=47 ;;
 153:      AIX | HP | SGI | SOLARIS )    COL=48 ;;
 154:      SUNBSD | DECOSF | SGI65 )     COL=57 ;;
 155:      ULTRIX )                      COL=51 ;;
 156:      * )  print "Unexpected system type." 1>&2
 157:           exit 1 ;;
 158:      esac
 159:     
 160:      ## Original code used a scratch file and loop to generate $DATAFILE
 161:      ## Replaced by piping through awk.
 162:      ps $PS_OPTS | sed '1d' | sort | awk '{print $2,$3,$1,substr($0,'$COL')}' > $DATAFILE
 163: fi
 164: 
 165: #
 166: # Print the current process.
 167: #
 168: ## Use internal arithmetic again, instead of calling 'expr'
 169: INDENT=$(( $LEVEL * 2 ))
 170: OUTLINE=`FillLine "" $INDENT`
 171: 
 172: LINE=`grep "^$PROCESS " $DATAFILE`
 173: set $LINE
 174: OUTLINE="$OUTLINE  $1"
 175: OUTLINE=`FillLine "$OUTLINE" 30`
 176: OUTLINE="$OUTLINE  $3	$4"
 177: print "$OUTLINE"
 178: 
 179: if [[ "$RECURSIVE" = "TRUE" ]];then
 180:      LEVEL=$(($LEVEL + 1))
 181:      while read LINE
 182:      do
 183:           set $LINE
 184:           #
 185:           # For every process that is a child of the
 186:           # current process, invoke this command ($0)
 187:           # recursively.
 188:           #
 189:           if [[ "$2" = "$PROCESS" ]]; then
 190:                $0 $1 $LEVEL $DATAFILE
 191:           fi
 192:      done <$DATAFILE
 193: fi
 194: 
 195: rm -f /tmp/*.$$
 196: exit 0



  last modified 22/03/2012 Introduction Table of Contents
(frame/no frame)
Printable
(single file)
© Dartmouth College