Perl:测试文件实际上是可写的而不是检查文件权限

Perl: Testing that a file is actually writable as opposed to checking file permissions

假设我有一个文件 /var/tmp/filename.

在 Perl 中,我编写了以下代码片段:

#!/usr/bin/env perl
use strict;
use warnings;

if (-W /var/tmp/filename)
{
...
}

exit;

-W 和 -w 函数 (http://perldoc.perl.org/functions/-X.html) 会检查文件是否确实可以写入,还是只检查文件权限是否允许写入?

我问的原因是我正在编写一个从服务器获取 cookie 的脚本。

此脚本需要能够将 cookie 文件写入文件系统,但如果 cookie 文件的文件系统路径是只读的,则文件权限无关紧要。所以我想测试 cookiefile 是否真的可写,而不是仅仅检查它的权限。

是的。您还可以执行以下操作:

if (-r $file && -w $file) {
    # file exists, I can read and write it
}

一般来说,-X 运算符只测试文件模式,而不是文件是否真的可写。所以你将不得不测试实际执行的操作,并发现任何失败。

来自 http://perldoc.perl.org/functions/-X.html :

The interpretation of the file permission operators -r , -R , -w , -W , -x , and -X is by default based solely on the mode of the file and the uids and gids of the user. There may be other reasons you can't actually read, write, or execute the file: for example network filesystem access controls, ACLs (access control lists), read-only filesystems, and unrecognized executable formats. Note that the use of these six specific operators to verify if some operation is possible is usually a mistake, because it may be open to race conditions.

我刚刚在我的测试系统 (Ubuntu 16.04) 上用一个文件中的文件系统的只读环回挂载验证了这一点,并且 -W 标志确实 错误地报告文件可以写入。

您可以使用触摸命令:

$ touch /media/MountPoint/testfile
touch: cannot touch '/media/MountPoint/testfile': Read-only file system

当 运行 使用 backtics 时,此 returns 成功时为零长度字符串:

unless (length `touch $filename`) 
{
    print "Can write\n";
}

如果您担心的是文件系统,您可以检查它是否以只读方式挂载。如果是这样,它在 /proc/mounts 中的行将有 ro,因此打开文件和 grep 包含 ro 和你的文件系统的行。

这仅适用于使用 /proc 但您的文件系统使用的文件系统。

请注意,使用 mount 进行查询不太可靠。

一个万无一失的方法是尝试写一个文件,我会使用 File::Temp

与 perl 相比,bash/sh shell test -w 命令会检查文件系统挂载,因此您可以使用它,例如

perl -e 'if (`[ -w . ] || echo NO`) {print "unwritable\n"}'