我试图弄清楚下面提到的 bash 代码到底是做什么的,特别是[-z $M ]
部分。这里 M 是一个有值的变量
if [ -z $M ] ; then
can not find module directory
exit 1
man test
Enter你看:
-z STRING
the length of STRING is zero
所以你的脚本确实如此,如果$M
长度==0,然后退出状态码1
正如其他人所说,它使用test
命令(aka [
)来检查字符串是否为空白。至少,这就是它想要做的。因为字符串 ( $M
) 没有被双引号引起来,所以它实际上做了一些稍微不同的事情。如果没有双引号, 的值$M
在被替换后会经历分词和通配符扩展,因此它可能不会被视为一个简单的字符串(-z
运算符处理的字符串)......可能会产生意想不到的后果。让我来看看一些可能性:
$M
的单个单词(非空白),则一切都按预期工作。*
?
如果 的值$M
为零长度(空白),则测试命令只会看到一个参数 ( -z
);当 test 只给出一个参数时,它只是测试它是否为空 - 它不是,所以它评估为真。
在这种情况下,这恰好是预期的结果,但这纯粹是巧合,对于许多其他运算符来说,这不是正确的结果。例如,[ -n $M ]
(看起来它应该测试是否$M
是*非*空白),[ -e $M ]
(看起来它应该测试是否$M
是文件/目录的名称)等如果$M
为空白,则都将评估为真。
$M
完全由空格组成(但不是空的),它会在test
看到它之前被消除,并test
评估为真(参见前面的案例)。这可能是脚本编写者的想法,也可能不是。如果 的值$M
有多个单词,test
将尝试将其评估为表达式的(部分)。它可能不是一个有效的表达式,在这种情况下test
会打印一个错误并返回 false(这是正确的......有点)。
另一方面,如果它是一个有效的表达式......例如假设你有,M='= -z
; test
将评估-z = -z
为真的表达式,而不是脚本编写者的想法。
如果 的值$M
有任何通配符,shell 将尝试将它们与文件匹配并传递test
匹配列表;它会尝试将它们评估为表达式(参见前面的案例),可能会给出错误并返回 false(再次,有点正确)。
请注意,如果您碰巧设置了 nullglob shell 选项并且通配符与任何文件都不匹配,则 shell 会将其替换为 null,并且脚本的行为就像 "u*n*m*a*t*c *h*e*d" 是空字符串。
这里的教训:如果你不希望你的脚本以奇怪和意想不到的方式表现,双引号你的变量引用!
这[
实际上是一个标准的 Unix 命令(可能在 Bash 内部实现,但无论您使用什么 shell 都可用)。它是命令的别名test
,因此可以通过键入找到它的手动条目man test
。这是该手册页的在线副本。
当调用 as 时[
,test
通常会期望它的最后一个参数是 a ]
,只是为了好看,所以[ -z $M ]
等效于test -z $M
.
在这种情况下,如果以下参数是长度为零的字符串,则该-z
参数会导致test
返回 true。变量$M
,在脚本的后面定义,因此可以测试一个有效值。
它检查变量的内容是否M
为空字符串。
检查此链接