经常搞迷糊shell脚本中的 $((expr))
、((1+2-3))
,也总是记不清是if ((1+2 > 3))
还是if $((1+2>3))
,今天写脚本又遇到了,查阅了bash命令的man手册,总算厘清了,整理一下,加深印象。
bash 中,有种语法叫ARITHMETIC EVALUATION
,支持整数四则运算。
-
$((expr))
叫Arithmetic Expansion
,其中的 expr 遵循ARITHMETIC EVALUATION
的规则。
$ echo $((1+2))
3
$ echo $((2**5))
32
-
((expression))
是shell中所谓”复合命令“中的一种(其它的有if,for,{ list } 等),其中的expression
遵循ARITHMETIC EVALUATION
的规则。
- 当数学表达式
expression
的计算结果等于零的时候,((expression))
的退出码是1 - 当数学表达式
expression
的计算结不等于零的时候,((expression))
的退出码是0
$ ((1+2))
$ echo $?
0
$ ((1+2-3))
$ echo $?
1
根据这一点,可以把((expression))
用在if语句的条件判断中,用来比较整数大小,比[[
命令更方便一些。
$ if ((689*128 > 2300)) ; then echo hello; fi
hello
# 用 [[ 的等价写法
$ if [[ $((689*128)) -gt 2300 ]];then echo hello; fi
hello
在shell脚本里经常需要判断上一个命令是否执行成功,用 if (($?))
就能做到
#!/bin/bash
# File: gbk_to_utf8.sh
# 把给定文件从GBK编码转换为 UTF-8 编码
# Example: ./gbk_to_utf8.sh foo
file="$1"
tmp_file=$(mktemp)
iconv -f GBK -t utf-8 "$file" > $tmp_file
if (($?)); then
echo "转换 $file 失败"
else
cat $tmp_file > "$file"
echo "转换 $file 完成"
fi
rm $tmp_file
ps:下面的写法和上面是等价的,节省了字符,但不够直观。
#!/bin/bash
# File: gbk_to_utf8.sh
# 把给定文件从GBK编码转换为 UTF-8 编码
# Example: ./gbk_to_utf8.sh foo
file="$1"
tmp_file=$(mktemp)
iconv -f GBK -t utf-8 "$file" > $tmp_file \
&& cat $tmp_file > "$file" \
|| echo "转换文件 $file 失败"
rm $tmp_file