我一直在尝试比较Bash中的两个数字是否相等(如果相等,则打印一条消息,但是对于这个简单的程序,我收到一些奇怪的错误消息:
#!/bin/bash
fun2 (){
$x = 3
//#prog.sh: line 4: =: command not found
if [x == 3]
then
//#prog.sh: line 6: [x: command not found
echo "It's 3!"
fi
}
fun2
导致错误的行下方显示了相应的错误。
必须是:
if [ $x -eq 3 ]; then .....
如果您希望使用更具可读性和自我解释性的代码,请使用以下语法:
if test $x -eq 3; then .....
解释:
要比较整数,您必须使用这些运算符(从man测试复制):
INTEGER1 -eq INTEGER2
INTEGER1 is equal to INTEGER2
INTEGER1 -ge INTEGER2
INTEGER1 is greater than or equal to INTEGER2
INTEGER1 -gt INTEGER2
INTEGER1 is greater than INTEGER2
INTEGER1 -le INTEGER2
INTEGER1 is less than or equal to INTEGER2
INTEGER1 -lt INTEGER2
INTEGER1 is less than INTEGER2
INTEGER1 -ne INTEGER2
INTEGER1 is not equal to INTEGER2
运算符==和!=仅用于字符串比较。
有关信息:“ [”命令是系统“测试”命令的别名。
Shell脚本并不是真的要成为一种完整的语言,它在很大程度上取决于其他外部命令的工作。
变量使用sigil,即在它们前面的$
。许多Shell脚本语言使用变量信号来帮助区分字符串和变量。
例如:
foo=foo_value
echo foo foo $foo foo
将打印:
foo foo foo_value foo
请注意,对于字符串的echo语句,引号不是必需的。 Windows Batch外壳非常相似:
set foo = foo_value
echo foo foo %foo% foo
如您所见,sigil用于假定要扩展的变量,但不定义变量时使用。那是因为Unix外壳是智能外壳。他们甚至在执行命令行之前就对命令行进行调整。外壳程序将替换环境变量之前执行:
foo=bar
$foo="whose value is this" #Note the dollar sign!
echo The value of foo is $foo
echo The value of bar is $bar
这将打印出来:
The value of foo is foo
The value of bar is whose value is this
如果使用set -xv
命令,您会看到$foo="whose value is this"
在执行之前已扩展为bar=whose value is this"
。
[在像Kornshell和BASH这样的Bourne风格的shell中,if
语句不是您想的那样。 if
命令执行该语句,如果该命令返回零值,则将选择if子句。例如:
cat "foo" > my_file #Create a one line file with the string foo in it.
if grep -q "foo" my_file #grep command will return a zero exit code if it finds foo
then
echo "The string 'foo' is in file my_file"
fi
注意if子句不是布尔型语句。这是一个实际执行的命令。
在Unix开发的早期某个地方,创建了test
命令。您可以进行man test并查看如何使用它。
test
命令允许您执行此操作:
foo=3
bar=3
if test foo -eq bar
then
echo "foo and bar are equal"
else
echo "foo and bar are not equal"
fi
如果您这样做:
$ ls -li /bin/test /bin/[
您将发现实际上存在一个名为[
的命令,并且是test
命令的硬链接。创建该代码的目的是使if
语句看起来更像是您在常规编程语言中将看到的if语句:
foo=3 bar=3 if [ foo -eq bar ] then echo "foo and bar are equal" else echo "foo and bar are not equal" fi
与上述脚本完全相同,但是使用
[
而不是test
。
这说明了为什么在许多测试中都需要破折号
(这是test
命令的参数,并且参数以破折号开头!)。它还说明了为什么在[
和]
周围需要空格。这些是实际的Unix命令,并且Unix命令周围必须有空格,以便Shell可以处理它们。另一个问题是为什么shell对字符串和数字进行两组不同的测试。这是因为字符串可能只包含数字,但实际上不是数字。例如,如果您进行库存管理,则零件编号可能为001
和01
。从数字上讲,它们是相等的,但作为字符串,它们是两个不同的字符串。 Shell脚本无法知道。相反,您必须让Shell脚本知道它是数字比较还是字符串比较。
Perl有类似的问题,因为您没有将变量声明为数字或非数字:
Shell Script Perl Boolean Operator Numeric String Numeric String =================== ======= ====== ======= ====== Equals -eq = == eq Not Equals -ne != != ne Greater Than -gt > > gt Less Than -lt < < lt Greater or Equals -ge >= >= ge Less Than or Equals -le <= <= le
您可以尝试其他一些事情:
命令之前通知shell expands$ echo "*" #Echos the asterisk $ echo * #No quotes: Prints all files in current directory
再次在执行echo
*
。这是Shell脚本和典型编程语言之间的主要区别。在实际执行命令之前,shell首先进行扩展(填充环境变量,glob替换,运行子命令)。set -xv
将向您显示正在执行的命令,以及在执行之前shell如何对命令进行[[expands
set +xv
将关闭该功能。尝试一下,您很快就会对外壳有了更好的了解。$
,等号=
周围不允许有空格[ ]
表达式中的空格是必需的,所以