“test -a file”和“test file -ef file”之间的区别

时间:2012-07-05 13:16:04

标签: ksh qnx

QNX(Neutrino 6.5.0)使用ksh的开源实现作为其shell。许多提供的脚本(包括系统启动脚本)都使用

等结构
if ! test /dev/slog -ef /dev/slog; then
    # do something
fi

检查文件系统中是否存在资源管理器。我搜索过,只能找到-ef检查这两个参数实际上是否是同一个文件的非常大的解释。由于指定的文件名是相同的,它似乎只是减少检查文件是否存在。

我检查了test -atest -e的行为(两者似乎都根据我读过的各种文档来检查任何类型文件的文件存在),它们似乎也有效。

-ef-a / -e之间执行的检查有何不同?是否使用-ef某种尝试来防止文件存在时的竞争条件?

2 个答案:

答案 0 :(得分:4)

在Ubuntu Linux的strace副本上查看ksh显示没有实质性差异。一次致电stat vs两次。

$ strace test /tmp/tmp.geLaoPkXXC -ef /tmp/tmp.geLaoPkXXC

显示了这个:

mmap(NULL, 7220736, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f11dc80b000
close(3)                                = 0
stat("/tmp/tmp.geLaoPkXXC", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
stat("/tmp/tmp.geLaoPkXXC", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
close(1)                                = 0
close(2)                                = 0

...而

$  strace test -a /tmp/tmp.geLaoPkXXC

显示了这个:

fstat(3, {st_mode=S_IFREG|0644, st_size=7220736, ...}) = 0
mmap(NULL, 7220736, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6b49e2b000
close(3)                                = 0
stat("/tmp/tmp.geLaoPkXXC", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
close(1)                                = 0
close(2)                                = 0

一个stat对两个。

$ ksh --version
  version         sh (AT&T Research) 93u 2011-02-08

答案 1 :(得分:1)

我们不知道代码如何在没有代码的情况下完全使用stat,我们需要通过代码找到差异。

/* code for -ef */
return (stat (argv[op - 1], &stat_buf) == 0
                  && stat (argv[op + 1], &stat_spare) == 0
                  && stat_buf.st_dev == stat_spare.st_dev
                  && stat_buf.st_ino == stat_spare.st_ino);


/* code for -e/-a */
    case 'a':                   /* file exists in the file system? */
    case 'e':
      return stat (argv[pos - 1], &stat_buf) == 0;

因此,如果名称相同且两个具有相同名称的stat()将返回相同的值,则, test -a/-e filetest file -ef file相同。我们知道第一个条件是正确的,我们知道第二个条件也来自@tinman的评论