Shell脚本中为何部分开发者会在if条件后添加分号?
关于Shell脚本中if语句几种写法的解析
嘿,刚接触Shell脚本遇到这种语法差异太正常了,我当初刚学的时候也对着各种写法懵圈!咱们把你提到的三种情况一个个掰扯清楚:
1. 带分号的单中括号写法:if [ $a == $b ]; then echo "a == b"; fi
首先得搞明白:[ 其实是一个内置命令(和test命令完全等价),不是语法符号!所以在同一行里,[ $a == $b ] 这个命令执行完之后,需要用分号;来分隔下一个命令then,不然Shell会把then当成[命令的参数,直接报错。
如果把代码拆成多行写,分号就可以省略,因为换行本身就起到了命令分隔的作用,比如:
if [ "$a" == "$b" ] then echo "a == b" fi
这里额外提醒一句:单中括号里的变量最好用双引号括起来!比如"$a",不然如果变量是空值或者包含空格,会直接触发语法错误(比如a为空时,[ $a == $b ]会变成[ == $b ],这显然不对)。
2. 你看到的“省略分号的单中括号写法”:if [ $a == $b ] then echo "a == b" fi
如果是同一行这么写,那这其实是错误的写法!你在Bash里测试应该会得到类似bash: syntax error near unexpected token 'then'的报错。只有把then单独换行,这种“省略分号”的写法才是合法的,就像上面拆成多行的例子那样。
3. 双中括号写法:if [[ $a == $b ]]; then echo "a == b"; fi
[[ ... ]]是Bash(还有zsh等现代Shell)提供的扩展语法,比单中括号功能强很多:
- 不需要给变量加双引号,空值或者带空格的变量都能正常处理;
- 支持模式匹配(比如
[[ $file == *.log ]]可以直接匹配后缀为.log的文件); - 支持逻辑运算符
&&、||,不用再用单中括号里的-a、-o; - 不会把
<、>当成重定向符号,直接用来做字符串比较就行。
同样,同一行里]]后面需要分号分隔then,换行的话可以省略:
if [[ $a == $b ]] then echo "a == b" fi
总结一下
- 单中括号
[ ... ]是POSIX标准写法,兼容所有Shell(比如sh),但要注意变量加引号,同一行必须用分号分隔]和then; - 双中括号
[[ ... ]]是Bash扩展,功能更灵活,但只在Bash/zsh等环境下可用,写法更宽松; - 同一行里省略分号的单中括号写法是错误的,只有换行写
then时才能省略分号。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

