-1

我试图弄清楚下面提到的 bash 代码到底是做什么的,特别是[-z $M ]部分。这里 M 是一个有值的变量

if [ -z $M ] ; then
    can not find module directory
    exit 1
4

4 回答 4

7
  1. man test Enter
  2. /-zEnter

你看:

-z STRING
              the length of STRING is zero

所以你的脚本确实如此,如果$M长度==0,然后退出状态码1

于 2013-05-30T22:33:42.880 回答
3

正如其他人所说,它使用test命令(aka [)来检查字符串是否为空白。至少,这就是它想要做的。因为字符串 ( $M) 没有被双引号引起来,所以它实际上做了一些稍微不同的事情。如果没有双引号, 的值$M在被替换后会经历分词和通配符扩展,因此它可能不会被视为一个简单的字符串(-z运算符处理的字符串)......可能会产生意想不到的后果。让我来看看一些可能性:

  • 如果 的值是没有通配符 ( and )$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" 是空字符串。

这里的教训:如果你不希望你的脚本以奇怪和意想不到的方式表现,双引号你的变量引用!

于 2013-05-31T01:40:48.320 回答
1

[实际上是一个标准的 Unix 命令(可能在 Bash 内部实现,但无论您使用什么 shell 都可用)。它是命令的别名test,因此可以通过键入找到它的手动条目man test。这是该手册页的在线副本

当调用 as 时[test通常会期望它的最后一个参数是 a ],只是为了好看,所以[ -z $M ]等效于test -z $M.

在这种情况下,如果以下参数是长度为零的字符串,则该-z参数会导致test返回 true。变量$M,在脚本的后面定义,因此可以测试一个有效值。

于 2013-05-30T22:38:10.363 回答
0

它检查变量的内容是否M为空字符串。

检查此链接

于 2013-05-30T22:35:43.227 回答