引号可以防止“单词分裂”。也就是说:将变量分解为多个空格字符(或更准确地说,是在默认$IFS
shell变量的值中定义的空格,制表符和换行符)。
例如,
$ var="one two"
$ howmany(){ echo $#; }
$ howmany $var
2
$ howmany "$var"
1
在这里,我们定义了一个howmany
函数,该函数仅让我们知道给出了多少个位置参数。如您所见,有两个项目传递给该变量,并且用引号将变量中的文本视为一个单位。
这对于准确传递信息很重要。例如,如果变量包含文件的路径,而文件名包含路径中任何位置的空格,则您尝试运行的命令可能会失败或给出不正确的结果。如果我们尝试使用$var
变量touch $var
创建文件,则将创建两个文件,但touch "$var"
只有一个。
您也一样[ "$currentoutput" != "$lastoutput" ]
。此特定测试对两个字符串进行比较。运行测试时,该[
命令将需要查看3个参数-一个文本字符串,!=
运算符和另一个文本字符串。保留双引号可以防止单词分裂,并且该[
命令可以准确地看到这三个参数。现在,如果变量不加引号怎么办?
$ var="hello world"
$ foo="hi world"
$ [ $var != $foo ]
bash: [: too many arguments
$
在这里,发生单词拆分,而是[
看到两个字符串hello
,world
然后是!=
,之后是两个其他字符串hi world
。关键是没有双引号,变量的内容应理解为单独的单位,而不是一个整体。
分配命令替换不需要双引号,如
var=$( df )
将df
命令输出保存到的位置var
。但是,$(...)
除非您确实希望将输出视为单独的项目,否则始终将引号和命令替换双引号是一个好习惯。
附带一提,
while [ true ]
部分可以是
while true
[
是一个评估其参数的命令,[ whatever ]
无论内部内容如何,该命令始终为true。相比之下,while true
使用true
总是返回成功退出状态的命令(而这正是while
循环所需要的)。区别是更加清晰,执行的测试更少。或者,您也可以使用:
代替true
echo "" date and Time
部分双引号可能会被删除。它们仅插入一个空字符串,并在输出中添加额外的空间。如果需要的话,请随时将它们保留在此处,但是在这种情况下没有特殊的功能价值。
lsusb >> test.log
这部分可能用代替echo "$currentoutput" >> test.log
。lsusb
已经在中运行后,没有理由再次运行currentoutput=$(lsusb)
。如果
必须在输出中保留结尾的换行符,则可以多次运行命令来看到该值,但是在lsusb
不需要时可以看到该值。调用的外部命令越少越好,因为每次调用非内置命令都会增加CPU,内存使用和执行时间的成本(即使这些命令可能是从内存中预先加载的)。
也可以看看:
while [ true ]
确实会产生无限循环,但可能并非出于您认为确实如此的原因。while [ false ]
还会产生一个无限循环,因为只有一个参数,[ ... ]
如果该参数是非空字符串,则成功。while true
实际上会运行一个名为true
(总是成功的)命令。