LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1542|回复: 5

---Bash 判断字符串是否为空(-n)

[复制链接]
发表于 2011-3-9 08:49:13 | 显示全部楼层 |阅读模式
大家好!

我发现在shell里面: -n string  的命令必须放在[[]]里面才正常,放在 []里面不对的, 而-z string放在[]里面就正常,何解?我看manpage没明白。

谢!
发表于 2011-3-12 11:38:19 | 显示全部楼层
Post by bzhao123;2130341
大家好!

我发现在shell里面: -n string  的命令必须放在[[]]里面才正常,放在 []里面不对的, 而-z string放在[]里面就正常,何解?我看manpage没明白。

谢!

我一直用 [ -n "$string" ],从未有过问题
回复 支持 反对

使用道具 举报

发表于 2011-3-13 21:32:36 | 显示全部楼层
  1. []
复制代码
只是test命令的同义词。
Bash分析命令的时候,会首先做变量替换,然后才执行命令。
例如:

  1. str=""
  2. [ -n $str ]  && echo true || echo false
复制代码

相当于:

  1. test -n $str && echo true || echo false
复制代码

而str为空,变量替换之后为空,由于没有放在引号里面,最后又会进行单词分割,于是得到

  1. test -n && echo true || echo false
复制代码

在Bash Manual中提到,当test命令有且仅有唯一一个不为空的参数时,总返回真值。这里唯一的参数是-n,所以这里返回true.
The test and [ builtins evaluate conditional expressions using a set of rules based on the number of arguments.

0 arguments
    The expression is false.
1 argument
    The expression is true if and only if the argument is not null.

至于"[["的结果为何不同。 这是因为"[["是Bash特殊的语法结构,不是test命令。 而且,双中括号里面不会进行单词分割,所以参数替换后的空值依然还在,能正确测试。
Word splitting and filename expansion are not performed on the words between the ‘[[’ and ‘]]’
Post by bzhao123;2130341
大家好!

我发现在shell里面: -n string  的命令必须放在[[]]里面才正常,放在 []里面不对的, 而-z string放在[]里面就正常,何解?我看manpage没明白。

谢!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-3-14 10:42:49 | 显示全部楼层
Post by biinn;2130759
我一直用 [ -n "$string" ],从未有过问题


你没错,在$string两边加上双引号就好了!因为以前好像这种情况会报错的!( 因位出现 if [ -n ];then  )
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-3-14 10:53:51 | 显示全部楼层
谢谢你的回复:

1. I know that  []  is the same as test command
2. 单词分割只是发生在命令后边吗?


Post by jacuro;2130927
  1. []
复制代码
只是test命令的同义词。
Bash分析命令的时候,会首先做变量替换,然后才执行命令。
例如:

  1. str=""
  2. [ -n $str ]  && echo true || echo false
复制代码

相当于:

  1. test -n $str && echo true || echo false
复制代码

而str为空,变量替换之后为空,由于没有放在引号里面,最后又会进行单词分割,于是得到

  1. test -n && echo true || echo false
复制代码

在Bash Manual中提到,当test命令有且仅有唯一一个不为空的参数时,总返回真值。这里唯一的参数是-n,所以这里返回true.

至于"[["的结果为何不同。 这是因为"[["是Bash特殊的语法结构,不是test命令。 而且,双中括号里面不会进行单词分割,所以参数替换后的空值依然还在,能正确测试。
回复 支持 反对

使用道具 举报

发表于 2011-3-14 14:42:04 | 显示全部楼层
单词分割与在命令前后毫无关系。
根据Bash参考手册 http://www.gnu.org/software/bash ... html#Word-Splitting

如果参数扩展,命令替换,算术扩展的结果没有被放到双引号里面,都会进一步做单词分割。
比如:

  1. cmd="which who"
  2. $cmd sh
复制代码

参数扩展之后,进行单词分割,最终得到的结果是

  1. which who sh
  2. #output
  3. /usr/bin/who
  4. /bin/sh
复制代码

若放到到引号里面,就不会进行单词分割,结果:

  1. "$cmd" sh
  2. -bash: which who: command not found
复制代码


在Bash中,“[[ ]]”里面的内容不会进行单词分割。 而"[ ]"会。
所以这样可以:

  1. var="Love Linux"
  2. [[ "Love Linux" = $var ]] && echo yes || echo no
复制代码

而这样会提示错误:

  1. var="Love Linux"
  2. [ "Love Linux" = $var ] && echo yes || echo no
  3. #命令输出
  4. -bash: [: too many arguments
  5. no
复制代码


另外一些"[[" 和"["的区别是:
1. "[["里面,表示比较的"<" , ">"不需要转义.
2. "[["里面,可以使用模式匹配及正则表达式

参考: http://www.gnu.org/software/bash ... ditional-Constructs
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表