内容

名称

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 filetestno filetest 语句影响其块中定义的文件测试,直到最近的封闭块结束(它们是词法块范围的)。

目前,仅实现了 access 子 pragma。它在可用时启用(或禁用)access() 的使用,即在大多数 UNIX 系统和其他 POSIX 环境中。请参见下面的详细信息。

仔细考虑

stat() 模式位可能适合系统上找到的大多数文件和目录,因为很少有人希望使用 access() 提供的其他功能。但是,如果您的程序在使用 ACL 的系统上运行,您可能会遇到意外情况,因为 stat() 信息不会反映实际权限。

当 filetest pragma 生效时,文件测试操作可能会略微降低性能,因为检查位非常便宜。

另外,请注意,将文件测试用于安全目的从一开始就是徒劳的:存在竞争条件的漏洞(谁又能说在测试和实际操作之间权限不会改变呢?)。因此,如果您认真对待安全性,请尝试实际操作并测试其成功性 - 以原子操作的方式思考。文件测试更适用于文件系统管理任务,当您不需要磁盘上元素的内容时。

“access”子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 版本中被移除。