linux shelltesting`-d`上的空参数

这里是代码,

x= if [ -d $x ]; then echo "it's a dir" else echo "not a dir" fi 

上面的代码给了我"it's a dir" ,为什么? $x是空的,不是吗?

 x= if [ -d $x ]; then 

相当于:

 if [ -d ] ; then 

一个简单的方法来演示是怎么回事:

 test -d ; echo $? 

打印0 ,表示测试成功( [实际上是一个命令,相当于test只是它需要终止]参数。)

但是这个:

 test -f ; echo $? 

做同样的事情。 这是否意味着缺少的参数是一个目录和一个纯文件?

不,这意味着它没有做这些测试。

根据test命令的POSIX规范,其行为取决于所收到的参数的数量。

有0个参数,它以1的状态退出,表示失败。

有1个参数,如果参数不为空,则退出状态为0(成功);如果参数为空,则退出1(成功)。

有2个参数,结果取决于第一个参数,它可以是! (反转1个参数的行为),或者像“ -f或“ -d ”或其他的“一元主” 如果是别的东西,结果是不明确的。

(POSIX也指定了超过2个参数的行为,但这与这个问题无关。)

所以这:

 x= if [ -d $x ]; then echo yes ; else echo no ; fi 

打印“是”,不是因为缺少的参数是一个目录,而是因为单个参数-d不是空字符串。

顺便说一句, GNU Coreutils手册没有提到这一点。

所以不要这样做。 如果要测试$x是否是一个目录,请用双引号括起来:

 if [ -d "$x" ] ; then ... 

stat系统调用,你的shell假定用来确定是否是一个目录,将null当作当前目录。

尝试编译这个程序,并运行它没有参数:

 #include <stdio.h> #include <sys/stat.h> int main(int argc, char* argv[]) { struct stat s ; stat(argv[1], &s) ; if(s.st_mode & S_IFDIR != 0) { printf("%s is a directory\n", argv[1]) ; } }