bash:数值太大不可为算数进制的基

在bash脚本中遇到一个错误,当数值过大时不能作为算术计算的基数。问题出现在使用0开头的数字,bash将其解析为八进制导致。通过修改数字表示方式解决了问题。bash的ARITHMETIC EVALUATION允许指定数值的进制,如2#、8#、16#等,并规定了不同进制的解析规则。

数值太大不可为算数进制的基

  • new,2022-08-19,chenxizhan1995@163.com

缘起

写了个脚本,每个小时执行一次,有一段逻辑要在当前时间为 21:00 ~ 21:59 时才执行。

		if (($(date +%H) == 21)); then
			echo 晚上 21 点,发送通知
			send mail/ok.txt
		else
			echo 时间不到,不发送通知
		fi

晚上写好,第二天早上看日志,八点执行的时候有一段报错

./main.sh:行25: ((: 08: 数值太大不可为算数进制的基 (错误符号是 "08")

if (($(date +%H) == 21)); 改成 if ((10#$(date +%H) == 21)); 就好了。

		if ((10#$(date +%H) == 21)); then
			echo 晚上 21 点,发送通知
			send mail/ok.txt
		else
			echo 时间不到,不发送通知
		fi

原理

bash 支持简单的数学计算,叫做 ARITHMETIC EVALUATION。在 $((expr))if ((expr))
中的表达式 expr 都遵循 ARITHMETIC EVALUATION 的规则。

bash 手册页 ARITHMETIC EVALUATION 章节对数值字面值有相关描述。
以 0 开头的字面值会按照八进制数字解析,所以 08 报错。同时允许手动指定字面值的进制。

$ echo $((1+2))
3
$ echo $((010))
8
$ echo $((10))
10
$ echo $((0x10))
16
$ echo $((018))
bash: 018: value too great for base (error token is "018")
# 手动指定为 10 进制
$ echo $((10#018))
18

附:

Constants with a leading 0 are interpreted as octal numbers. A leading 0x or 0X
denotes hexadecimal. Otherwise, numbers take the form [base#]n, where the optional
base is a decimal number between 2 and 64 representing the arithmetic base, and n is a
number in that base. If base# is omitted, then base 10 is used. When specifying n,
the digits greater< than 9 are represented by the lowercase letters, the uppercase
letters, @, and _, in that order. If base is less than or equal to 36, lowercase and
uppercase letters may be used interchangeably to represent numbers between 10 and 35.

  1. 可以指定数值的进制,格式为 base#number,比如二进制 2#110,八进制 8#6,十六进制 16#6,十进制 10#6
  2. 不指定数值进制时,
    • 以 0 开头时,是八进制的数值,例如 017 等价于 8#017
    • 以 0x 或 0X 开头时是 16 进制,例如 0x17 等价于 16#17
    • 否则是十进制,例如 17 等价于 10#17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值