仅在alpine linux上出现算术语法错误
我对bash非常陌生,今天才开始编写一个小的调度程序。在mac和ubuntu上测试后,一切正常。但当我想在alpine linux中执行它时,抛出了一个错误:算术语法错误。我不明白为什么会这样,也找不到谷歌叔叔的解决方案。我希望有人能帮助我 这是一个表达:仅在alpine linux上出现算术语法错误,linux,bash,alpine,Linux,Bash,Alpine,我对bash非常陌生,今天才开始编写一个小的调度程序。在mac和ubuntu上测试后,一切正常。但当我想在alpine linux中执行它时,抛出了一个错误:算术语法错误。我不明白为什么会这样,也找不到谷歌叔叔的解决方案。我希望有人能帮助我 这是一个表达: [ $((10#$(date +"%H%M") != 10#$START_TIME)) = 1 ] 在显示如何运行的上下文中: #!/bin/bash START_TIME=2100 END_TIME=2200 # arithmeti
[ $((10#$(date +"%H%M") != 10#$START_TIME)) = 1 ]
在显示如何运行的上下文中:
#!/bin/bash
START_TIME=2100
END_TIME=2200
# arithmetic syntax error
while [ $((10#$(date +"%H%M") != 10#$START_TIME)) = 1 ]; do
sleep 10;
done
此代码依赖于未指定POSIX的语法,以确保将值解析为十进制数,即使它们以0开头 简单的答案是“不要这样做”——也就是说,如果需要使用基线POSIX解释器,可以使用字符串比较而不是数字比较,或者以不同的方式修剪前导0 坚持数字路线:例如,在作业中使用
sed
效率很低,但它可以:
START_TIME=2100 # this already doesn't start with a 0
while [ $(( $(date +"%H%M" | sed -e 's/^0+//') != START_TIME )) = 1 ]; do
sleep 10
done
或者,直接使用字符串比较:
START_TIME=2100 # exactly four digits
while [ "$(date +"%H%M")" != "$START_TIME" ]; do
sleep 10
done
你可以在阿尔卑斯山之外复制它——只需要测试
sh
由ash
或dash
实现的任何地方。顺便说一句,我假设你运行sh scriptname
?因为它有一个#/bin/bash
shebang,表示它被编写为仅在安装了bash
的系统上运行,并使用bash
作为其解释器。Alpine不运送bash——它有更小、启动更快的外壳,比如dash
@CharlesDuffy。。嗯?注意你的注释<代码>当我现在删除的答案在单词< /代码>的中间时,它不被当作一个注释。天啊,天啊。感谢您的洞察力。:)感谢您的快速回答,对于最有效的方式,您希望脚本的外观如何?如果您希望在启动后优化运行时效率,我将安装bash而不是使用/bin/sh
——这样您就可以用printf%(%H%M)替换date
T'
并且根本没有任何调用外部进程的子shell。(请注意,在没有子shell的情况下这样做意味着一个单独的赋值;即,在printf-v current_time%%(%H%M)T'&&[$current_time!=$START_time]];do
--注意,我正在从数字比较切换到字符串比较;没有理由进行数字比较以进行精确的相等性检查)。如果我正确地收集到您希望使用下面的测试对每个printf
进行分组,这可能看起来像:而{printf-v current_day%%(%a)T'-1&[${DAYS,,}!=*”${current_day,,}“*]”;}{printf-v current_time%%(%H%M)T'-1&[$current_time!=$STOP_time]]};do
。顺便说一句,天
、当前时间
和停止时间
都是大写;请参见第四段:所有大写名称都用于对操作系统或shell有意义的变量;其他名称保留给应用程序使用。(-1
s表示“当前时间”;在没有警告的情况下抛出警告,即使printf
在这两种情况下都做了正确的事情)。