if [ -z "$BASH_VERSINFO" ]; then
echo "Please make sure you're using bash!"
exit 1
fi
readonly prog_name=$(basename "$0")
is_writeable() {
local var="$1"
is_writeable_empty "${var}" 0
}
is_writeable_empty() {
local var="$1"
local empty="$2"
[[ -z "${empty}" ]] && empty=1
if { touch -a "${var}" >/dev/null 2>&1; }; then
if [[ ! -s "${var}" ]]; then
if [[ ! -w "${var}" ]]; then
return 1
fi
else
[[ "${empty}" -eq 1 ]] && return 1
fi
else
return 1
fi
return 0
}
is_number() {
local int="$1"
[[ "$int" != *[!0-9]* ]]
}
is_empty() {
local var="$1"
[[ -z "$var" ]]
}
show_error() {
printf "\n%s\n" "${prog_name}: error: $*" >&2
exit 1
}
show_warning() {
printf "\n%s\n" "${prog_name}: $*" >&2
}
show_help() {
cat <<- EOF
Usage: ${prog_name} [options] <command> [<logfile>]
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Arguments:
<command> Slowpoke command
<logfile> Where <command>'s output will be saved
Default: \$RANDOM-output.log
Options:
-i, --interval <int> Refresh interval in sec.
Default: 30
-l, --limit <int> Limit execution time in sec.
Default: 0 (Off)
-x, --exit-code <int> Force the exit code
Default: -1 (Off)
-a, --append <int> PRN append output to existing logfile
Off: 0 (Default)
On: 1
-h This help screen
Copyright (C) 2015 m3t
The MIT License (MIT)
EOF
exit 0
}
cleanup() {
kill -0 ${pid_slowpoke} >/dev/null 2>&1 && kill ${pid_slowpoke} >/dev/null 2>&1
}
main() {
local i=0
local msg=""
local time_passed=0
local pid_slowpoke=0
local exit_slowpoke=0
local interval=30
local time_limit=0
local exit_force=-1
local append=0
local cmd_slowpoke=""
local file_log=""
trap 'cleanup; trap - INT; kill -INT $$' INT QUIT trap 'cleanup; exit 1' TERM
msg="requires a non-empty option argument."
while :; do
case "$1" in
-h|-\?|--help)
show_help
exit
;;
-l|--limit)
if [ -n "$2" ]; then
time_limit="$2"
shift 2
continue
else
show_error "--limit ${msg}"
fi
;;
--limit=?*)
time_limit="${1#*=}"
;;
--limit=)
show_error "--limit ${msg}"
;;
-i|--interval)
if [ -n "$2" ]; then
interval="$2"
shift 2
continue
else
show_error "--interval ${msg}"
fi
;;
--interval=?*)
interval="${1#*=}"
;;
--interval=)
show_error "--interval ${msg}"
;;
-x|--exit-code)
if [ -n "$2" ]; then
exit_force="$2"
shift 2
continue
else
show_error "--exit-code ${msg}"
fi
;;
--exit-code=?*)
exit_force="${1#*=}"
;;
--exit-code=)
show_error "--exit-code ${msg}"
;;
-a|--append)
if [ -n "$2" ]; then
append="$2"
shift 2
continue
else
show_error "--append ${msg}"
fi
;;
--append=?*)
append="${1#*=}"
;;
--append=)
show_error "--append ${msg}"
;;
--) shift
break
;;
-?*)
show_warning "Unknown option (ignored): $1"
;;
*) break
esac
shift
done
cmd_slowpoke="$1"
file_log="$2"
is_number "${interval}" || show_error "Interval is not a valid number"
is_number "${time_limit}" || show_error "Limit is not a valid number"
is_empty "${cmd_slowpoke}" && show_error "Command to execute is not given. See --help."
is_empty "${file_log}" && file_log="$RANDOM-output.log"
if [[ "${append}" -ne 1 ]]; then
is_writeable_empty "${file_log}" || show_error "${file_log} is not writeable or not empty."
${cmd_slowpoke} > >(tee "${file_log}") 2>&1 & pid_slowpoke=$!
else
is_writeable "${file_log}" || show_error "${file_log} is not writeable."
${cmd_slowpoke} > >(tee -a "${file_log}") 2>&1 & pid_slowpoke=$!
fi
i=0
while kill -0 ${pid_slowpoke} >/dev/null 2>&1; do
: $(( time_passed = i * interval ))
printf "%s\n" \
"Still waiting for about ${time_passed} seconds" \
"Used disk space: $(du -sh .)"
if [[ "${time_limit}" -ne 0 ]] && [[ "${time_passed}" -ge "${time_limit}" ]]; then
cleanup
break
fi
sleep ${interval}
: $(( i += 1 ))
done
if ! is_number "${exit_force}"; then
wait ${pid_slowpoke}; exit_slowpoke=$?
else
exit_slowpoke=${exit_force}
fi
show_warning "Your given command has terminated with exit code $exit_slowpoke. So do I."
exit ${exit_slowpoke}
}
main "$@"