More info at https://norswap.com/nps-pkill-pgrep/
Last active
February 27, 2024 20:35
-
-
Save norswap/3506d2b46102c2f32f18acced0ecd798 to your computer and use it in GitHub Desktop.
norswap's process tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# ps version: "ps from procps-ng 3.3.17" | |
### --- 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="cut -c -$(tput cols)" # command to clip command names (or not) | |
else | |
COLOR='--color=none' | |
CLIP='\cat' | |
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-[s]ensitive 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" \ | |
" The PID is always also included in the matched fields (as additional\n" \ | |
" first field). 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,ses ,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 2022.06.16-linux; exit;; | |
-*) help; exit 1;; | |
*) POSITIONAL+=("$1");; | |
esac | |
shift | |
done | |
set -- "${POSITIONAL[@]}" "$@" # restore positional parameters | |
if [[ "$KILL" == "1" && (-z "$*" || "$*" == " ") ]]; then | |
echo "Attempting to kill with no search string or single space search string." | |
exit 1 | |
fi | |
### --- Match PIDs --- | |
filter_header_and_grep() { | |
$TAIL_CMD | grep -v "$(which nps)" | grep -v " grep " | |
} | |
select_pids() { | |
grep $CASE -E -- "$*" | awk '{ print $1 }' | |
} | |
if [[ "$MATCH_FIELDS" == "-o pid" ]]; then | |
# if matching on PID only, only match whole PIDs | |
MATCH_FIELDS=-"p $*" | |
else | |
# include pid at start | |
MATCH_FIELDS="-o pid,${MATCH_FIELDS#-o }" | |
fi | |
# find matching PID | |
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 | |
ps $OUTPUT_FIELDS -p $PIDS | tr -d '\r' | $STRIP_HEADER | highlight_matches "$*" | cut -c -$(tput cols) | |
EXIT=$? | |
### --- Kill --- | |
# kill matched processes if requested | |
if [[ $KILL == 1 ]]; then | |
kill -9 $PIDS | |
EXIT=$? | |
fi | |
exit $EXIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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-[s]ensitive 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" \ | |
" The PID is always also included in the matched fields (as additional\n" \ | |
" first field). 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.06.16-mac; exit;; | |
-*) help; exit 1;; | |
*) POSITIONAL+=("$1");; | |
esac | |
shift | |
done | |
set -- "${POSITIONAL[@]}" "$@" # restore positional parameters | |
if [[ "$KILL" == "1" && (-z "$*" || "$*" == " ") ]]; then | |
echo "Attempting to kill with no search string or single space search string." | |
exit 1 | |
fi | |
### --- Match PIDs --- | |
filter_header_and_grep() { | |
$TAIL_CMD | grep -v "$(which nps)" | grep -v " grep " | |
} | |
select_pids() { | |
grep $CASE -E -- "$*" | awk '{ print $1 }' | |
} | |
if [[ "$MATCH_FIELDS" == "-o pid" ]]; then | |
# if matching on PID only, only match whole PIDs | |
MATCH_FIELDS=-"p $*" | |
else | |
# include pid at start | |
MATCH_FIELDS="-o pid,${MATCH_FIELDS#-o }" | |
fi | |
# 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