Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅在alpine linux上出现算术语法错误_Linux_Bash_Alpine - Fatal编程技术网

仅在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

我对bash非常陌生,今天才开始编写一个小的调度程序。在mac和ubuntu上测试后,一切正常。但当我想在alpine linux中执行它时,抛出了一个错误:算术语法错误。我不明白为什么会这样,也找不到谷歌叔叔的解决方案。我希望有人能帮助我

这是一个表达:

[ $((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
在这两种情况下都做了正确的事情)。