filetest - Perl 语言用于控制文件测试权限运算符的 pragma
$can_perhaps_read = -r "file"; # use the mode bits
{
use filetest 'access'; # intuit harder
$can_really_read = -r "file";
}
$can_perhaps_read = -r "file"; # use the mode bits again
此 pragma 告诉编译器更改文件测试权限运算符的行为,-r
-w
-x
-R
-W
-X
(参见 perlfunc)。
文件测试运算符的默认行为是使用 stat() 函数族返回的简单模式位。但是,许多操作系统具有其他功能来定义更复杂的访问权限,例如 ACL(访问控制列表)。对于此类环境,use filetest
可能有助于权限运算符返回与其他工具更一致的结果。
use filetest
或 no filetest
语句影响其块中定义的文件测试,直到最近的封闭块结束(它们是词法块范围的)。
目前,仅实现了 access
子 pragma。它在可用时启用(或禁用)access() 的使用,即在大多数 UNIX 系统和其他 POSIX 环境中。请参见下面的详细信息。
stat() 模式位可能适合系统上找到的大多数文件和目录,因为很少有人希望使用 access() 提供的其他功能。但是,如果您的程序在使用 ACL 的系统上运行,您可能会遇到意外情况,因为 stat() 信息不会反映实际权限。
当 filetest pragma 生效时,文件测试操作可能会略微降低性能,因为检查位非常便宜。
另外,请注意,将文件测试用于安全目的从一开始就是徒劳的:存在竞争条件的漏洞(谁又能说在测试和实际操作之间权限不会改变呢?)。因此,如果您认真对待安全性,请尝试实际操作并测试其成功性 - 以原子操作的方式思考。文件测试更适用于文件系统管理任务,当您不需要磁盘上元素的内容时。
UNIX 和 POSIX 系统提供了一个抽象的 access() 操作系统调用,应该使用它来查询读、写和执行权限。此函数隐藏了各种不同的方法,以及其他操作系统特定的安全特性,例如访问控制列表 (ACL)。
扩展的文件测试功能仅在操作符的参数是文件名时才被 Perl 使用,而不是在它是文件句柄时。
_
的限制因为 access() 不调用 stat()(至少不是以 Perl 可见的方式),stat 结果缓存“_”不会被设置。这意味着以下两个测试的结果不同。第一个在_
中包含/etc/passwd的 stat 位,而第二个情况下,它仍然包含/etc
的位。
{ -d '/etc';
-w '/etc/passwd';
print -f _ ? 'Yes' : 'No'; # Yes
}
{ use filetest 'access';
-d '/etc';
-w '/etc/passwd';
print -f _ ? 'Yes' : 'No'; # No
}
当然,除非您的操作系统没有实现 access(),在这种情况下,pragma 就会被忽略。最好不要在启用文件测试 pragma 的文件中使用_
!
作为副作用,由于_
不起作用,堆叠的文件测试操作符(-f -w $file
)也不起作用。
这个限制可能会在未来的 Perl 版本中被移除。