QNX(Neutrino 6.5.0)使用ksh的开源实现作为其shell。许多提供的脚本(包括系统启动脚本)都使用
等结构if ! test /dev/slog -ef /dev/slog; then
# do something
fi
检查文件系统中是否存在资源管理器。我搜索过,只能找到-ef
检查这两个参数实际上是否是同一个文件的非常大的解释。由于指定的文件名是相同的,它似乎只是减少检查文件是否存在。
我检查了test -a
和test -e
的行为(两者似乎都根据我读过的各种文档来检查任何类型文件的文件存在),它们似乎也有效。
-ef
和-a
/ -e
之间执行的检查有何不同?是否使用-ef
某种尝试来防止文件存在时的竞争条件?
答案 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 file
与test file -ef file
相同。我们知道第一个条件是正确的,我们知道第二个条件也来自@tinman的评论