I wrote the following bash script as a budgeting tool to more accurately calculate (and moderate) when I last bought a pack of cigarettes.
In addition to -h for printing the output, it takes one other option: -b with (what is intended to be) an optional parameter to set the offset in hours. So -b 5 logs a new pack of cigs bought 5 hours ago, and subsequent runs of cigs.sh indicate how many weeks, days or hours it's been since then. If the elapsed time since the last time I bought a pack is less than $threshold, the output is printed in red; if the elapsed time is more than $threshold, the output is green, indicating it's now "okay" for me to buy a new pack.
I've managed to get all this working fine except for one thing: it's currently not possible to specify -b without an offset (i.e. log the purchase as being made right now instead of some hours into the past). As far as I've been able to tell this seems to be a limitation of getopts: without the colon in b:h, $OPTARG fails to populate causing the logic in the b) case option to fail; with the colon, it prevents -b from being used without a parameter, throwing the following error:
/usr/local/bin/scripts/cigs.sh: option requires an argument -- b
Unknown parameter passed: -b
Here is the getopts portion of my script:
while getopts "b:h" OPTION; do
case $OPTION in
h)
echo "$usage"
exit
;;
b)
offset=$OPTARG
if [[ -n $offset && ! $offset =~ ^[0-9]+$ ]]; then
echo "HOURS parameter passed to -b must be an integer."
exit
fi
echo -e "Bought a new $item...\nResetting timer to 0 days and $offset hours."
offset=$((offset*60*60))
last_bought="$(date -u +%s)"
new_lb=$((last_bought-offset))
echo $new_lb > $lb_file
exit
;;
*)
echo "Unknown parameter passed: $1"
exit 1
;;
esac
done