2011-12-27 73 views
5

对于unix文件,我想知道群组或世界是否对文件具有写权限。如果文件权限大于755,如何检查Perl?

我一直在思考这些线路上:

my $fpath = "orion.properties"; 
my $info = stat($fpath) ; 
my $retMode = $info->mode; 
$retMode = $retMode & 0777; 

if(($retMode & 006)) { 
    # Code comes here if World has r/w/x on the file 
} 

感谢。

回答

11

你接近你的建议 - 的stat的使用是有点过(但转念一想,你必须使用File::stat;它帮助,如果你的代码完成),面具不变的是错误的,并注释叶子有点不理想:

use strict; 
use warnings; 
use File::stat; 

my $fpath = "orion.properties"; 
my $info = stat($fpath); 
my $retMode = $info->mode; 
$retMode = $retMode & 0777; 

if ($retMode & 002) { 
    # Code comes here if World has write permission on the file 
}  
if ($retMode & 020) { 
    # Code comes here if Group has write permission on the file 
} 
if ($retMode & 022) { 
    # Code comes here if Group or World (or both) has write permission on the file 
} 
if ($retMode & 007) { 
    # Code comes here if World has read, write *or* execute permission on the file 
} 
if ($retMode & 006) { 
    # Code comes here if World has read or write permission on the file 
} 
if (($retMode & 007) == 007) { 
    # Code comes here if World has read, write *and* execute permission on the file 
} 
if (($retMode & 006) == 006) { 
    # Code comes here if World has read *and* write permission on the file 
} 
if (($retMode & 022) == 022) { 
    # Code comes here if Group *and* World both have write permission on the file 
} 

在提问标题的术语“如何检查在Perl中,如果该文件的权限比755更大?即集团/世界有写入许可“有点可疑。

该文件可能拥有权限022(或更合理的是622),并且包含组和世界写入权限,但这两个值都不能合理地声称为“大于755”。

我发现有用的一组概念是:

  • 集位 - 位在权限字段必须是1
  • 复位位 - 位在权限字段必须为0
  • 不关心位 - 可以设置或重置的位。

例如,对于一个数据文件,我可能需要:

  • 套装0644(所有者可以读,写,组和其他可以读取)。
  • 重置0133(所有者无法执行 - 它是一个数据文件;组和其他无法写入或执行)。

更可能的是,对于一个数据文件,我可能需要:

  • 套装0400(所有者必须能够读取)。
  • 重置0133(没有人可以执行;组和其他不能写入)。
  • 不在乎0244(无论所有者是否可以写;无论组或其他人都可以阅读)。

目录略有不同:执行权限意味着可以使目录成为当前目录,或访问目录中的文件,如果你知道他们的名字,而读取权限意味着你可以找出哪些文件目录,但如果没有执行权限,则无法访问它们。因此,您可能有:

  • 设置0500(所有者必须能够读取和使用目录中的文件)。
  • 重置0022(组和其他人不能修改目录 - 删除或添加文件)。
  • 不在意0255(不在乎用户是否可以创建文件;不关心群组或其他人是否可以列出或使用文件)。

请注意,置位和复位位必须是不相交的(($set & $rst) == 0)),位总和将始终为0777;可以从0777 & ~($set | $rst)计算“无关”位。

+2

请使用[Fcntl](http://p3rl.org/Fcntl)模式常量('S_I *')而不是幻数。 – daxim 2011-12-27 17:54:11

+2

对于像我这样老古板的人来说,这些常数比'Fcntl'中的字母表汤更容易阅读。单独地,常量的可读性更高,但'S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH'比'0755'更难读取。但是,使用字母汤可能是更好的风格。我想我可以定义一个方便的常量:'使用常量S_I755 =>(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);'? (是的,这是一个笑话。)也许'使用常量S_RWXR_XR_X =>(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);'更可口。 – 2011-12-27 18:10:47

-3
#!/usr/bin/perl 

use warnings; 
use strict; 

chomp (my $filename = <STDIN>); 

my $lsOutput = `ls -l $filename`; 

my @fields = split (/ /,$lsOutput); 

my @per = split (//,$fields[0]); 

print "group has write permission \n" if ($per[5] eq 'w'); 

print "world has write permission" if ($per[8] eq 'w'); 
+0

解析'ls'的输出是不可靠的;也不是有效或必要的。 Perl具有内置的必要功能。 – 2011-12-27 17:46:59