This is my first Bash script and I decided to use what I've learned so far to help manage stray processes while I develop in my *nix environs.
I've tested the script extensively and it seems to work (there may be some things I have not caught yet).
If I could get some critiques/tips on the script that would be great.
I named the file process
and placed it in my ~/bin folder so that I could execute it like any other program.
#!/bin/bash
# kill processes using SIGQUIT signal -- still in testing
PROGNAME=$(basename $0)
function _usage_notice {
echo "Usage: $PROGNAME [ help | show | destroy ] [ arg(s)... ]"
}
function _usage_summary {
echo "Usage: $PROGNAME [ action ] [ arg(s)... ]
Summary
-------
This script is designed to send a quit signal event to a
running program. If multiple instances of that program
exist, they are all sent the same signal.
Action Description
------ -----------
show Shows current processes for current user.
kill
destroy Sends SIGQUIT signal to given process if
given process exists.
help Outputs this help text.
"
}
function _usage_processes {
echo "Usage: $PROGNAME [ show ] [ user | root | unsorted | sorted | less ]
Examples
--------
$PROGNAME show
Executes 'ps' with the format 'pid,user,comm'
$PROGNAME show user
Executes 'ps' and outputs 'user' owned processes
$PROGNAME show root
Executes 'ps' and outputs 'root' owned processes
$PROGNAME show [ unsorted | all ]
'all' and 'unsorted' are synonymous and displays all processes
$PROGNAME show sorted
Executes 'ps' and outputs 'all' processes in sorted order by user
$PROGNAME show less
Executes 'ps' and pipes 'all' output to 'less' if 'less' exists
"
}
function _usage_destroy {
echo "Usage: $PROGNAME [ destroy ] [ command(s)... ]
Examples
--------
$PROGNAME destroy nautilus
Sends the SIGQUIT signal to the process 'nautilus'
$PROGNAME destroy [ program(s)... ]
You can pass multiple programs all at once as well.
$PROGNAME destroy nautilus bash pithos firefox
Sends the SIGQUIT signal to given processes
"
}
function _usage_help {
echo "Usage: $PROGNAME [ help ] [ show | destroy | help ]
Examples
--------
$PROGNAME
Outputs basic usage
$PROGNAME help
Outputs usage summary
$PROGNAME help [ show | destroy | help ]
Outputs usage information for given action
"
}
function _usage_full {
case $1 in
"show") _usage_processes ;;
"destroy"|"kill") _usage_destroy ;;
"help") _usage_help ;;
*) echo "Invalid argument given to action help." ;;
esac
}
# test if a valid action was given
function _is_valid_action {
case $1 in
"destroy"|"kill") echo valid ;;
"show") echo valid ;;
"help") echo valid ;;
*) echo "" ;;
esac
}
# test if action has no arguments
function _input_is_empty {
while [[ 0 -lt "$#" ]]; do
if [[ -n $(_is_valid_action $1) ]]; then
shift
if [[ -n $(_is_valid_action "$1") ]]; then
echo valid
break
fi
continue
elif [[ -n "$1" ]]; then
echo valid
break
else
echo ""
break
fi
done
}
# show current processes according to given arguments
function _processes {
case "$1" in
"user") ps -U $USER -o pid,tty,user,comm ;;
"root") ps -U root -o pid,tty,user,comm ;;
"all"|"unsorted") ps -A -o pid,tty,user,comm ;;
"sorted") ps -A --sort=user -o pid,tty,user,comm ;;
"less") if [[ -n $(which less) ]]; then
ps -A --sort=user -o pid,tty,user,comm | less
else
echo "'less' is not installed."
fi ;;
*) ps -o pid,user,comm ;;
esac
}
# send to quit signal to given processes
function _destroy {
while [[ 0 -lt "$#" ]]; do
pid=$(pgrep $1)
if [[ -z "$pid" ]]; then
echo "Process '$1' does not exist."
exit 2
fi
for item in $pid; do
kill -SIGQUIT $pid
echo "Destroyed process '$item' named '$1'"
done
shift
done
}
function _prompt {
echo "Warning! This function uses pattern matching!"
echo "This is DANGEROUS because multiple processes may be selected!"
read -p "Are you sure you want to continue? [y/yes/n/no]> " answer
case $answer in
"y"|"yes") clear
echo "You were Warned! Starting in 5 seconds..."
sleep 5
return ;;
"n"|"no") exit 2 ;;
esac
}
case $1 in
"show")
shift
_processes "$@"
;;
"destroy"|"kill")
if [[ -z $(_input_is_empty "$@") ]]; then
echo "No arguments were given to destroy."
exit 1
fi
shift
_prompt
_destroy "$@"
;;
"help")
if [[ -z $(_input_is_empty "$@") ]]; then
_usage_summary
exit 0
fi
shift
_usage_full "$@"
;;
*) # default
_usage_notice
exit 1
;;
esac
exit 0