我正在尝试为Linux / Unix类编写一个简单的bash脚本,并且不断收到语法错误。连我的教授也一眼也看不出来。
任何见解将不胜感激!
pattersoncode:~ austen$ ./bash2
./bash2: line 3: if[ =0 ]: command not found
./bash2: line 4: syntax error near unexpected token `then'
./bash2: line 4: `then'
pattersoncode:~ austen$
问候,
a=6
test $a -eq 6 > b
if[ "$b"="0" ]
then
echo True
else
echo False
fi
在BASH中,白色空间极为重要。
很抱歉大喊大叫,但这需要强调。与其他脚本语言(例如Perl或Python)不同,Bash对空白极为敏感。例如:
foo="bar" # No spaces around the equal sign.
foo = "bar" # This is a syntax error because of the spaces around the equal sign
if [ "$foo" = "bar" ] # You need spaces around the equal sign.
then
...
fi
if [ "$foo"="bar" ] # Syntax error: You forgot the spaces around the equal sign.
then
...
fi
外壳不解释变量。它插值变量。有细微的差别。
在Shell执行命令之前,它将运行干扰。它查找环境变量并将其替换为它们的值。(它还会删除glob,并将它们也替换为匹配的文件)。
例如,这些在Perl中都有效:
if ( $foo == $bar ) {
if($foo==$bar) {
if ($foo== $bar) {
这是因为Perl会解释该行,因此即使没有空格,它也会将$foo
和$bar
视为变量。即使$foo
和$bar
为空,也没有问题。Perl知道您正在将变量$foo
的值与变量的值进行比较$bar
。
但是,外壳的运行方式不同,它会进行插值。在if
执行该语句之前,shell会删除环境变量并将其替换为其值。然后,只有这样,shell才会执行该if
语句。
if [ $foo = $bar ]
假设设置为,$foo
则为空白:$bar
banana
外壳看到以下内容:
if [ $foo = $bar ]
并用$foo
和$bar
为其指定的值替换:
if [ = banana ]
那是语法错误。您缺少等号左侧的值。在较旧的Shell脚本中,您会看到类似以下内容:
if [ x$foo = x$bar ]
在这种情况下,shell将删除环境变量并将其替换为其值:
if [ x = xbanana ]
这是一个有效的文本比较。这是另一个有趣的事实。想象一下,如果$foo
等于等于字符串-f
而$bar
为空:
if [ $foo = $bar ]
现在将插值为:
if [ -f = ]
而且,这是有效的。它询问是否=
存在一个名为的文件。
解决此问题的方法是始终在变量周围加上引号。这个:
if [ "$foo" = "$bar" ]
将被插值为:
if [ "-f" = "" ]
这是一个有效的字符串比较。
顺便说一句,您需要在空格周围,[
因为这不是语法问题,而是命令!
执行一个ls /bin/[
,您将看到这[
是一个Unix命令。它与链接/bin/test
。
从而:
if [ "$foo" = "$bar" ]
实际上与:
if test "$foo" = "$bar"
并且,这就是为什么在等号周围也需要空格的原因。的=
是将一个参数test
命令。
现在,查看您的错误,看看您是否可以准确找出它们的含义:
./bash2: line 3: if[ =0 ]: command not found
当然,if[
这不是命令。你忘记了周围的空白[
。此外,$b
没有任何价值,这就是为什么您在那看不到它的原因。
您可以做的整洁的事情之一就是添加set -xv
到Shell脚本中。这将打开详细信息并进行调试。您将能够看到shell看到的命令,然后看到shell如何插入该命令。这是捕获错误的好方法。
顺便说一句,该if
命令的实际语法为:
if command
该if
语句运行命令。如果命令返回的退出代码为零,则该语句被认为是正确的,因此将执行的then
部分if
。这是做什么的[ ... ]
。(记住,我说的[
是命令)。该[ ... ]
试验被执行。如果为真,则执行语句的then
一部分if
。否则,该else
子句(如果存在)。
您会一直在shell脚本中看到这样的事情:
if ! rm "$foo"
then
echo "File '$foo' was removed."
else
echo "Can't remove file '$foo'."
fi
请注意,我只是在运行rm
,而是if
用来测试rm
命令是否成功。
对不起罗explanation的解释。Shell不是普通的脚本语言,除非您了解Shell的运行方式,否则很难理解正在发生的事情。使用set -xv
打开调试并set +xv
关闭它。
同样有趣的是,尝试以下两个语句,看看会发生什么:
$ echo * # No quotes
$ echo "*" # Quotes around the asterisk
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句