在Shell脚步执行的时候我们经常会遇到“xxx: unexpected operator”这个错误,其实这个错误一般都是因为我们的表达式有问题,这里我们举一个出错率非常高的例子:

#!/bin/bash

param="cat test.txt | grep allan";

if [ $param = "allan" ]; then
	echo "allan exists in test.txt"
fi

这一个脚本执行的时候,如果param的值为空就会出现“test.sh: 5: [: cat: unexpected operator”,因为当param为空时,第五行就变为“if [  = "allan" ]”,这显然是不对的。

这种情况在我们写shell脚本时出现的几率很大,但这个很容易造成隐藏的bug。当变量不为空的时候程序可以正常运行,但是当变量为空的时候,就会出现错误。解决的方法也很简单,就是在表达式中,将变量都用双引号括起来,这样即使变量为空的时候,程序也可以正常运行,不会出现语法错误。比如改成下面这个样子:

#!/bin/bash

param="cat test.txt | grep allan";

if [ "$param" = "allan" ]; then
	echo "allan exists in test.txt"
fi

所以,推荐大家在写Shell脚本的时候,尽量多用双引号将变量引起来。虽然大多数情况下,加不加双引号都是一样的,但是在一些情况下,双引号可以帮助我们避免很多bug。比如下面也是一种情况:

#!/bin/bash

param="123"

echo "1st line: $param456"
echo "2nd line: $param 456"
echo "3rd line: $param"456
echo "4th line: ${param}456"

程序输出为:

1st line:
2nd line: 123 456
3rd line: 123456
4th line: 123456

可以看到,

第一行输出为空,因为系统认为我们要打印的变量是$param456,但这个变量不存在,也就是值为空。

第二行,我们在$param后面加了一个空格,打印正常。

第三行,我们用双引号将变量引起来,也可正常打印。

第四行,我们用大括号将变量括起来,也可正常打印。

结论:在Shell脚本中,表达式中的变量尽量用双引号/大括号引起来。