使用文件stat在perl中查找文件的模式

时间:2013-08-17 09:29:33

标签: perl

我正在尝试一个示例程序来获取文件的用户模式。

#! /usr/bin/perl 
use strict;
use warnings;
use File::stat;

my $file_name = 0;
my $info = 0;
my $ret_mode = 0;
foreach(@ARGV){
$file_name = $_;
$info = stat($file_name);
$ret_mode  = $info->mode;
print "Before : $ret_mode\n";
$ret_mode = $ret_mode & 0777;
print "After : $ret_mode\n";

if($ret_mode & 070){
 print "$file_name has Read,Write & Execute permission\n";
}
elsif($ret_mode & 060){
 print "$file_name has Read and write permission\n";
}
elsif($ret_mode & 050){
 print "$file_name has Read and execute permission\n";
}
elsif($ret_mode & 030){
 print "$file_name has Write and Execute permission\n";
}
elsif($ret_mode & 020){
 print "$file_name has Write permission\n";
}
elsif($ret_mode & 010){
 print "$file_name has Execute Permission\n";
}
elsif($ret_mode & 040){
 print "$file_name has Read Permission\n";
}
else{
 #nothing;
}
$ret_mode = 0;
}        

我尝试了一个示例程序,以查找我作为参数提供的文件的用户权限。 我无法理解为什么$ ret_mode必须和0777(组,用户和所有者)一起获取模式值。
上面的代码没有给我正确的权限。 请帮助理解$ info->模式包含的内容以及我们需要的原因以及0777.

编辑:

OUPUT :

angus@ubuntu~/ perl 5.pl 1.pl 2.pl

Before : 32784
After : 16
1.pl has Read and execute permission
Before : 33188
After : 420

i / p文件1.pl和2.pl不读取,执行和写入,执行权限。上面的程序输出了错误的结果。

ls -l <​​/ h2>
-----w---- 1 angus angus  174 2013-08-16 00:33 1.pl
-rw-r--r-- 1 angus angus  455 2013-08-16 08:33 1.txt
-rw-r--r-- 1 angus angus  245 2013-08-16 02:10 2.pl

1 个答案:

答案 0 :(得分:2)

仅当您想要将结果显示为整体时才需要0777技巧,而不是如果您想要根据蒙版进行测试。要查看差异,请输入目录或软链接作为脚本的参数。

如果您只是测试&运算符是否返回任何内容,则应从最具体的模式开始,即反转逻辑。如果文件仅具有写入权限,则其模式为020,但020 & 070不为零:

    4 2 1
 ========
 7  1 1 1
 2  0 1 0
 --------
 &  0 1 0

另一种选择是检查返回值,即

if (020 == ($ret_mode & 020)) {

要遵守DRY(不要重复自己)原则,您也可以使用哈希来缩短代码:

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

use File::stat;

my %name = ( 070 => 'Read,Write & Execute',
             060 => 'Read and write',
             050 => 'Read and execute',
             030 => 'Write and Execute',
             020 => 'Write',
             010 => 'Execute',
             040 => 'Read',
           );
my @modes = reverse(040, 010, 020, 030, 050, 060, 070);

for my $file_name (@ARGV) {
    my $info     = stat($file_name);
    my $ret_mode = $info->mode;
    printf "Before: %o\n", $ret_mode;
    $ret_mode &= 070;
    printf "After: %o\n", $ret_mode;
    for my $mode (@modes) {
        print "$file_name has $name{$mode} permission.\n" and last
            if ($ret_mode & $mode) == $mode;
    }
}