linux中的test命令失效现象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux中的test命令失效现象相关的知识,希望对你有一定的参考价值。

linux中test命令:
unset name
test -z $name && echo "empty" || echo "not empty"
显示:empty
test -n $name && echo "empty" || echo "not empty"
显示:empty

我的问题来了,为什么对于没有设置的变量,test对此的长度检测失效,到底出现什么问题

不是test失效, 而是 test 命令没有得到足够的参数.


原因是shell 在解释命令时, 会"先"对命令行进行扩展, 使用变量实际的值替换到命令行中, 然后再执行命令.


上面unset name后, $name的值为空, 执行完命令行扩展后, 实际执行的是


test -z && echo "empty" || echo "not empty"


此时, shell 实际传给test 命令的参数只有一个 "-z",  这种情况下, test 的退出码总是0


所以在执行的时候, 使用双引号将变量名引起来是个好习惯, 这样命令行扩展后实际传给test的参数为2个(尽管第2个只是一个空字符串)


关于shell 的命令行扩展, 除了变量, 还有一些其它的工作, 


见下例: a.sh

#!/bin/bash

echo $#
echo $@

执行 ./a.sh a1,2,3 输出为

 ./a.sh a1,2,3

3

a1 a2 a3

看起来是传给命令行一个参数 a1,2,3, 实际上执行完shell 扩展后, 传给a.sh 的参数是 a1 a2 a3 共3个参数.


关于shell 扩展的更多细节, 详见bash 的man page的 EXPANSION 这一节.

参考技术A 将$name用引号括起来追问

你看一下上面啊锋哥的回答。

不觉得有点奇怪。

怎么讲?

name被解释成空字符串了。

追答

null和空字符串是不同的事物
如果不加引号就编程null了,加了引号是空字符串

追问

我说的有点急,说反了。

为什么上面的name被解释成非空字符。

求详细点

追答

这和shell对命令行的解释过程有关
当你在命令行下输入一条命令,并按下回车,shell开始对该命令进行解释,解释成它能够理解的东西

在name变量没有被定义的情况下
test -z $name,在解释时$name的位置由于name没有被定义,name的值是null,这段命令你给就被解释成了
test -z
test -z “$name”,在解释时$name的位置由于name没有被定义,虽然name的值是null,但是它的外面还有一个引号,name变量这是作为引号括起来的字符串的一部分,该段命令被解释成了
test -z ""
空字符串与什么都没有的null是不同的,空字符串在内存中也都对应的存储空间,而null是没有的

以上是关于linux中的test命令失效现象的主要内容,如果未能解决你的问题,请参考以下文章

linux sudo命令中的%sudo ALL=(ALL:ALL) ALL 括号中的冒号表示啥意思呢?

2-11 Linux 中的文件处理 --- mkdir、rmdir 创建目录和删除空目录命令

在linux后台运行脚本的方法和命令

Linux Shell中的命令替换

linux 替换 sed命令 转载

Linux 基本命令--ls 常用命令