0

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

#! /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(group,user and owner) 一起获得模式值。
上面的代码没有给我正确的权限。请帮助理解 $info->mode 包含的内容以及我们为什么需要和 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

-----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
4

1 回答 1

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;
    }
}
于 2013-08-17T09:39:12.973 回答