我编写了以下 bash
脚本作为预算工具,以更准确地计算(和适度)我上次购买一包香烟的时间。
除了-h
打印输出之外,它还有一个选项:-b
使用(预期的)一个可选参数来设置偏移量(以小时为单位)。因此,-b 5
记录 5 小时前购买的一包新香烟,随后的运行cigs.sh
表明从那时起已经过了多少周、几天或几小时。如果自上次购买包以来经过的时间小于$threshold
,则输出为红色;如果经过的时间超过$threshold
,则输出为绿色,表示我现在可以购买新包了。
我已经设法让所有这些工作正常,除了一件事:目前无法指定-b
没有偏移量(即,将购买记录为现在进行而不是过去几个小时)。据我所知,这似乎是一个限制getopts
:如果没有冒号b:h
,$OPTARG 无法填充,导致b)
case 选项中的逻辑失败;使用冒号,它可以防止-b
在没有参数的情况下使用,引发以下错误:
/usr/local/bin/scripts/cigs.sh:选项需要一个参数
--b 传递的未知参数:-b
这是getopts
我的脚本的一部分:
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
这里非常有趣的问题。根据我对工作原理的了解
getopts
,使用单个冒号 (:
) 意味着必须设置选项值:如果你希望它是可选的,你需要设置两个冒号 (
::
) 并且没有任何如下内容:但这
hb::
不起作用。我玩弄了您的脚本,这是我可以开始工作的唯一解决方案。它改变了你
getopts "b:h"
,getopts "bh"
所以两个选项参数都是可选的。但神奇的是在b)
案例中添加更多代码,所以整个while
块现在看起来像这样:魔法来自这里的这个块,它基于另一个 Stack Overflow对关于同一问题的问题的回答:
显然没有工作时预期的那么干净
getopts "hb::"
,但事实并非如此,所以这个 kludge 工作。如果其他对 Bash 更有经验的人可以解释原因——或者提出更简洁的解决方案——他们应该发布它。现在,这行得通,所以它行得通!