我正在尝试为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
答案 0 :(得分:4)
白色空间在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不会解释变量。它插入变量。有一个微妙的区别。
在shell执行命令之前,它会运行干扰。它查找环境变量并用它们的值替换它们。 (它也会删除整数并用匹配的文件替换它们。)
例如,这些在Perl中都是有效的:
if ( $foo == $bar ) {
if($foo==$bar) {
if ($foo== $bar) {
那是因为Perl 解释了这一行,因此它将$foo
和$bar
视为变量,即使空格不在那里也是如此。即使$foo
和$bar
为空,也没有问题。 Perl理解您将变量$foo
的值与变量$bar
的值进行比较。
但是,shell运行方式不同,它插入。在执行if
语句之前,shell 删除环境变量,用它们的值替换。然后,只有这样shell才会执行if
语句。
if [ $foo = $bar ]
假设$foo
为$bar
而banana
设置为if [ $foo = $bar ]
时,我们假设{/ 1}}:
shell看到了这个:
$foo
并使用指定的值替换$bar
和if [ = banana ]
:
if [ x$foo = x$bar ]
这是一个语法错误。你错过了等号左边的值。在较旧的shell脚本中,您将看到如下内容:
if [ x = xbanana ]
在这种情况下,shell将删除环境变量并用它们的值替换它们:
$foo
这是一个有效的文本比较。这是另一个有趣的事实。想象一下,如果-f
等于字符串$bar
,而if [ $foo = $bar ]
为空,那么
if [ -f = ]
现在将插值 as:
=
而且,这是有效的。它询问是否存在名为if [ "$foo" = "$bar" ]
的文件。
解决这个问题的方法是始终在变量周围加上引号。这样:
if [ "-f" = "" ]
将插值为:
[
这是一个有效的字符串比较。
顺便说一句,ls /bin/[
周围需要空格,因为这不是一些语法,它是一个命令!
执行[
,您会看到/bin/test
是Unix命令。它与if [ "$foo" = "$bar" ]
。
因此:
if test "$foo" = "$bar"
实际上与:
相同=
而且,这就是为什么你也需要等号周围的空间。 test
是./bash2: line 3: if[ =0 ]: command not found
命令的参数。
现在,看看你的错误,看看你是否能弄清楚它们的含义:
if[
当然,[
不是命令。你忘记了$b
周围的空白区域。此外,set -xv
没有价值,这就是为什么你在那里看不到它。
您可以做的一件好事是将if
添加到您的shell脚本中。这将打开详细和调试。您将能够看到shell看到的命令,然后查看shell如何插入该命令。这是捕获错误的好方法。
顺便说一下,if command
命令的实际语法是:
if
then
语句运行该命令。如果该命令返回退出代码为零,则该语句被视为true,因此执行if
的{{1}}部分。这就是[ ... ]
的作用。 (记住,我说[
是一个命令)。执行[ ... ]
测试。如果是,则执行then
语句的if
部分。否则,else
子句(如果存在)。
你会一直在shell脚本中看到这样的东西:
if ! rm "$foo"
then
echo "File '$foo' was removed."
else
echo "Can't remove file '$foo'."
fi
注意我只是运行rm
而我正在使用if
来测试rm
命令是否成功。
对罗嗦的解释感到抱歉。 Shell不是一种普通的脚本语言,除非您了解shell的运行方式,否则很难理解正在发生的事情。使用set -xv
启用调试,set +xv
启用调试功能。
另外,为了好玩,试试这两个陈述,看看会发生什么:
$ echo * # No quotes
$ echo "*" # Quotes around the asterisk
答案 1 :(得分:0)
你可以通过许多不同的方式来做到这一点。这只是一个:
#!/bin/bash
a=6
test $a -eq 6
b=$? # Here you store the error exit code
if [ "$b" = "0" ]
then
echo True
else
echo False
fi
### short and cryptic bash version :-)
aa=7
test $aa -eq 7 && echo True2 || echo False
在bash
中可以用简短的方式编写构造
if test_condition
then
...
else
...
fi
与
test_condition && ... || ...
其中&&
扮演then
角色,||
扮演else
角色。