Skip to content

Instantly share code, notes, and snippets.

@norswap norswap/nps
Last active Mar 25, 2020

Embed
What would you like to do?
norswap's process tool
#!/bin/bash
### --- Constants ---
SCRIPT_CMD='script -q /dev/null'
TAIL_CMD='tail -n +2'
### --- Parameters ---
ALL='' # flag to match all users process
CASE='-i' # flag for case-insensitive matches
KILL=0 # if 1, kill matched processes
# ps fields to match on
MATCH_FIELDS='-o pid,command'
# ps fields to output
OUTPUT_FIELDS='-o pid,command'
# command used to strip the header (or not)
STRIP_HEADER="$TAIL_CMD"
if [[ -t 1 ]]; then
COLOR='--color=always' # whether to colorize output
CLIP="$SCRIPT_CMD" # command to clip command names (or not)
else
COLOR='--color=none'
CLIP=''
fi
### --- Help ---
help() {
echo -e "Usage: nps <opts or search terms> [-- <search terms>]\n" \
" Print processes.\n" \
" -a: include processes from [a]ll users\n" \
" -s: case-sensitive match\n" \
" -k: [k]ill the mached processes\n" \
" -h: print this [h]elp and exit\n" \
" -l: print the [l]ist of selectable fields and exit\n" \
" -m <fields>: specify comma-separated list of field to [m]atch on\n" \
" If specifying only '-m pid', only matches entired PIDs. \n" \
" -o <fields>: specify comma-separated list of fields to [o]utput\n" \
" -v: [v]erbose output, equivalent to\n" \
" -o 'user, pid, ppid, pgid, sess ,jobc, state, tt, time, command' \n" \
" --color: [c]olorize output even when piping to programs\n" \
" --header: include fields (columns) header in output\n" \
" --full: output full command name even if stdout is a terminal\n" \
" --clip: output clipped command name even if stdout is not a terminal\n" \
" --version: print version and exit\n";
}
### --- Arg Parsing ---
POSITIONAL=()
while [[ $# -gt 0 ]]; do case "$1" in
-a) ALL='-a';;
-s) CASE='';;
-v) OUTPUT_FIELDS="-o user, pid, ppid, pgid, sess, jobc, state, tt, time, command'";;
-o) OUTPUT_FIELDS="-o $2"; shift;;
-m) MATCH_FIELDS="-o $2"; shift;;
-k) KILL=1;;
-l) ps -L; exit;;
-h|--help) help; exit;;
--) shift; break;;
--color) COLOR='--color=always';;
--header) STRIP_HEADER='cat';;
--full) CLIP='';;
--clip) CLIP="$SCRIPT_CMD";;
--version) echo 2020.03.22; exit;;
-*) help; exit 1;;
*) POSITIONAL+=("$1");;
esac
shift
done
set -- "${POSITIONAL[@]}" "$@" # restore positional parameters
### --- Match PIDs ---
filter_header_and_grep() {
$TAIL_CMD | grep -v "$(which nps)" | grep -v " grep "
}
select_pids() {
grep $CASE -E -- "$*" | awk '{ print $1 }'
}
# if matching on PID only, only match whole PIDs
[[ "$MATCH_FIELDS" == "-o pid" ]] && MATCH_FIELDS=-"p $*"
# find matching PIDs
PIDS="$(ps -x $ALL "$MATCH_FIELDS" | filter_header_and_grep | select_pids "$*")"
# when no process is found: exit with 1, or with 0 when the -k flag is set
[[ "$PIDS" == '' ]] && { [[ $KILL == 1 ]]; exit $?; }
### --- Output ---
highlight_matches() {
if [[ "$*" == '' ]]; then cat; else grep $COLOR $CASE -E "($*)|$"; fi
}
# print with requested fields + highlighting
# the tr command cleans up the script command output
$CLIP ps -x "$OUTPUT_FIELDS" -p $PIDS | tr -d '\r' | $STRIP_HEADER | highlight_matches "$*"
EXIT=$?
### --- Kill ---
# kill matched processes if requested
if [[ $KILL == 1 ]]; then
kill -9 $PIDS
EXIT=$?
fi
exit $EXIT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.