在ubuntu下运行shell脚本的时候,出现了“nohub_start.sh: [[: not found”的错误,但是直接在shell终端中运行脚本中的代码没有问题,后来发现由于在shell脚本开头有“#!/bin/sh”来定义使用哪种sh解释器来解释脚本,而ubuntu下/bin/下,通过ls -l /bin/sh发现sh -> dash,如此使用“bash *.sh”来执行或者脚本开头修改为“#!/bin/bash”,这样就可以了。鉴于这个问题,总结下语法上bash和dash的区别。
一、[[ ]]扩展
bash 支持[[ ]], 可实现正则匹配等功能
root@ojlab:~# [[ 1 = 3 ]]
root@ojlab:~#
dash 不支持[[ ]]
#[[ 1 = 3 ]]
dash: 7: [[: not found
二、==和=相等的比较
bash 都支持
root@ojlab:~# [ 1 == 2 ]
root@ojlab:~# echo $?
1
root@ojlab:~# [ 1 == 1 ]
root@ojlab:~# echo $?
0
root@ojlab:~# [ 1 = 1 ]
root@ojlab:~# echo $?
0
root@ojlab:~#
dash 只支持=
# [ 1 == 1 ]
dash: 1: [: 1: unexpected operator
# [ 1 = 1 ]
# echo $?
0
# [ 1 = 3 ]
# echo $?
1
三、定义函数
bash 支持function
root@ojlab:~# function foo() { echo "hello"; }
root@ojlab:~# foo
hello
dash 不支持function
# function foo() { echo "hello"; }
dash: 17: Syntax error: "(" unexpected
#
四、类C风格的for循环
bash 支持类C风格的for循环(for((expr1; expr2; expr3)) do command command ... done)
root@ojlab:~# for ((integer = 1; integer <= 5; integer++)); do echo "$integer"; done
1
2
3
4
5
root@ojlab:~#
dash 不支持此类风格语法,但可以使用类似while的语句来替代
# integer=0; while [ $integer -le 5 ]; do echo $integer; integer=$((integer+1)); done
0
1
2
3
4
5
#
五、let命令和((expression))
bash 有内置命令let, 也支持((expression))方式
root@ojlab:~# i=0
root@ojlab:~# let i++
root@ojlab:~# echo $i
1
root@ojlab:~# let i++
root@ojlab:~# echo $i
2
root@ojlab:~#
dash 不支持,但可以采用$((expression))或者外部命令做计算
# i=0
# i=$((i+1))
# echo $i
1
# i=$((i+1))
# echo $i
2
#
六、++和--运算符
bash 支持i++,i--,++i,--i运算
root@ojlab:~# i=0
root@ojlab:~# echo $((i++))
1
root@ojlab:~# echo $((i++))
2
root@ojlab:~# echo $i
3
dash 不支持此类运算符,但支持+=,-=运算
# i=0
# echo $((i++))
dash: 33: arithmetic expression: expecting primary: "i++"
# echo $i
0
# echo $((i+=1))
1
# echo $i
1
七、select语句
bash 支持select语句
root@ojlab:~# select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do break; done
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
root@ojlab:~# echo "You have selected $var"
You have selected Linux
root@ojlab:~# select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do break; done
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 3
root@ojlab:~# echo "You have selected $var"
You have selected Free BSD
root@ojlab:~#
dash 不支持,但可以使用while+read+case替代
#while read var
do
case $var in
1)
echo "Linux"
break
;;
2)
echo "Gnu Hurd"
break
;;
3)
echo "Free BSD"
break
;;
*)
echo "Other"
break
;;
esac
done
2
Gnu Hurd break
八、{n..m}展开
bash 支持{n..m}展开
root@ojlab:~# echo {1..10}
1 2 3 4 5 6 7 8 9 10
root@ojlab:~#
dash 不支持,但可以使用seq命令替代
# echo {1..10}
{1..10}
# echo `seq 1 10`
1 2 3 4 5 6 7 8 9 10
#
九、数组
bash 支持数组
root@ojlab:~# array=( 1 2 4 )
root@ojlab:~# echo ${array[1]}
2
root@ojlab:~#
dash 不支持数组
# array=( 1 2 4 )
dash: 117: Syntax error: "(" unexpected
以上是工作中经常遇到的需要注意的语法点,习惯上大家使用bash shell多一些,为了通用性最好还是采用bash语法并使用bash来解析shell脚本。