# --- enable/disable this file --- SRC_ENABLED=true case "$SRC_ENABLED" in 1|true|yes|on) unset SRC_ENABLED ;; # enabled — clean up and continue *) unset SRC_ENABLED; return ;; # disabled — clean up and skip this file esac # --------------------------------- bash_pstree() { local root_pid="${1:-1}" local procdir pid key value name ppid idx PIDS=() PPIDS=() NAMES=() idx=0 # # Build process table from /proc/*/status. # for procdir in /proc/[0-9]*; do [[ -d "$procdir" ]] || continue [[ -r "$procdir/status" ]] || continue pid="${procdir#/proc/}" name="" ppid="" while IFS=: read -r key value; do value="${value#"${value%%[![:space:]]*}"}" case "$key" in Name) name="$value" ;; PPid) ppid="$value" ;; esac done < "$procdir/status" [[ -n "$ppid" ]] || continue PIDS[$idx]="$pid" PPIDS[$idx]="$ppid" NAMES[$idx]="${name:-?}" idx=$((idx + 1)) done bash_pstree_set_chars bash_pstree_root "$root_pid" } # # Pick UTF-8 box-drawing chars if the locale supports them, else # fall back to plain ASCII (works on any RHEL5 console/terminal). # bash_pstree_set_chars() { local charmap charmap=$(locale charmap 2>/dev/null) if [[ "$charmap" == "UTF-8" ]]; then BPT_VERT="│ " BPT_TEE="├── " BPT_LAST="└── " else BPT_VERT="| " BPT_TEE="|-- " BPT_LAST="\`-- " fi } bash_pstree_find_name() { local target="$1" local i for ((i = 0; i < ${#PIDS[@]}; i++)); do if [[ "${PIDS[$i]}" == "$target" ]]; then printf '%s' "${NAMES[$i]}" return 0 fi done return 1 } # # Print numerically-sorted child PIDs of $1, one per line. # bash_pstree_children() { local parent="$1" local i list list="" for ((i = 0; i < ${#PIDS[@]}; i++)); do if [[ "${PPIDS[$i]}" == "$parent" ]]; then list="$list${PIDS[$i]} " fi done [[ -n "$list" ]] && printf '%s' "$list" | sort -n } bash_pstree_root() { local pid="$1" name name=$(bash_pstree_find_name "$pid") || return printf '%s(%s)\n' "$name" "$pid" bash_pstree_show_children "$pid" "" } # # $1 = parent pid, $2 = prefix accumulated so far # bash_pstree_show_children() { local parent="$1" prefix="$2" local child name last_line local children children=$(bash_pstree_children "$parent") [[ -n "$children" ]] || return last_line=$(printf '%s\n' "$children" | tail -n 1) while IFS= read -r child; do [[ -n "$child" ]] || continue name=$(bash_pstree_find_name "$child") || continue if [[ "$child" == "$last_line" ]]; then printf '%s%s%s(%s)\n' "$prefix" "$BPT_LAST" "$name" "$child" bash_pstree_show_children "$child" "${prefix} " else printf '%s%s%s(%s)\n' "$prefix" "$BPT_TEE" "$name" "$child" bash_pstree_show_children "$child" "${prefix}${BPT_VERT}" fi done <<< "$children" } # # Wrapper: # # pstree_compat # pstree_compat 1234 # pstree_compat() { local root_pid="${1:-1}" if command -v pstree >/dev/null 2>&1; then pstree -p "$root_pid" else bash_pstree "$root_pid" fi } alias pstree='pstree_compat'