6

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

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

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

我已经检查了test -aand的行为test -e(两者似乎都根据我读过的各种文档检查任何类型文件的文件存在)并且它们似乎也可以工作。

-ef-a/之间执行的检查有什么区别-e吗?是否正在使用-ef某种尝试来防止文件存在的竞争条件?

4

2 回答 2

4

查看straceUbuntu Linux 上的副本ksh没有发现实质性差异。一打stat对二打。

$ 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
于 2012-07-13T03:39:40.043 回答
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 的评论中我们知道第二个条件也为真

于 2012-07-13T15:28:52.590 回答