Skip to content

Instantly share code, notes, and snippets.

@jcausey-astate
Last active March 17, 2018 16:58
Show Gist options
  • Save jcausey-astate/9a37f2a2f91f693aaa1e7d473d88c2b6 to your computer and use it in GitHub Desktop.
Save jcausey-astate/9a37f2a2f91f693aaa1e7d473d88c2b6 to your computer and use it in GitHub Desktop.
Watches a running process, executing a specified command when it finishes (Bash).
#!/bin/bash
script="$(basename ${0})"
read -r -d '' USAGE <<-EOF
Watches a specified process (by pid or name) and runs
a specified command after it exits.
If watching by name, the command executes when no process
by that name is running.
Usage:
${script} [-a|-A] [-t seconds] pid cmd
${script} [-a|-A] [-t seconds] -n name cmd
${script} -h
pid the process id of the process to monitor
cmd a command to run when the monitored process exits
-a uses \`ps -a\` when searching for processes
-A uses \`ps -A\` when searching for processes
-h print this usage message and exit
-n name monitor for presence of any running process named
\`name\`, not by pid
-t seconds set delay between polling attempts to \`seconds\` (default 5)
EOF
by_name=0
delay=5
dash_a=""
# process command arguments
while [[ "${1:0:1}" == "-" ]] ; do
if [[ "${1}" == "-a" ]] || [[ "${1}" == "-A" ]] ; then
dash_a="${1}"
shift
elif [[ "${1}" == "-n" ]] || [[ "${1}" == "--name" ]] ; then
shift
by_name=1
name=${1}
pid=${1}
shift
elif [[ "${1}" == "-t" ]] || [[ "${1}" == "--time" ]] ; then
shift
delay=${1}
shift
elif [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]] ; then
shift
echo
echo "${USAGE}"
echo
exit 0
fi
done
if [[ -z ${name} ]] ; then
name="${1}"
pid="${1}"
shift
fi
cmd="$@"
# Do some sanity checking
if [[ -z ${pid} ]] || [[ -z ${cmd} ]] ; then
echo
echo "Error: Not enough arguments given."
echo
echo "${USAGE}"
echo
exit 1
fi
isint_re='^[0-9]+$'
if [[ ${by_name} -eq 0 ]] && ! [[ ${pid} =~ ${isint_re} ]] ; then
echo
echo "Error: PID must be an integer. (Saw '${pid}'.)"
echo
echo "${USAGE}"
echo
exit 2
fi
if ! [[ ${delay} =~ ${isint_re} ]] ; then
echo
echo "Error: Delay must be an integer. (Saw '${delay}'.)"
echo
echo "${USAGE}"
echo
exit 3
fi
# Now we can do the work
echo "Waiting on ${pid}, then running: ${cmd}"
first_check=0
while true; do
if [[ $by_name -ne 0 ]] ; then
pid=$(ps ${dash_a} | grep -m1 -e "[0-9]\s*${name}" | awk '{print $1}')
fi
kill -0 $pid 2>/dev/null
if [[ $? -ne 0 ]] ; then
if [[ ${first_check} -ne 0 ]] ; then
$cmd
exit $?
else
echo
echo "Error: The process '${name}' does not appear to be running!"
echo " Maybe you need the -a or -A option?"
echo
echo "${USAGE}"
echo
exit 4
fi
fi
sleep ${delay}
first_check=1
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment