2

Guys im trying to see the permission of a certain file in perl using stat.

So when i did this

foreach (@original_files) {
    my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev,
      $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat ($_);

    print "$mode \n";
}

this outputs:

33204 which corresponds to the permission -rw-rw-r--

which i cant understand why is it 33204. <-- This is my first question

Next is i tried converting the $mode to octal which i know is the number system for umask.

this is my code:

printf ("%0\n",$mode);

now this outputs 100664 which i quite undersand the last 3 digits (rw-rw-r--) but i dont understand where did the first 3 digits come from ( the 100 in the 100664) That is my second question

Lastly is i tried this code again:

printf ("%o\n", $mode & 775); #im not sure about the 775, or is it 577

That last code is what i desired. It outputs 664. And my question is why when i AND the $mode to i forgot the value (775 or something) it outputs the right permission.?

And OT question too: What is the difference of $_ and @_?

4

2 回答 2

6

From my web host's man 2 stat about mode:

S_IFMT     0170000   bit mask for the file type bit fields
S_IFSOCK   0140000   socket
S_IFLNK    0120000   symbolic link
S_IFREG    0100000   regular file
S_IFBLK    0060000   block device
S_IFDIR    0040000   directory
S_IFCHR    0020000   character device
S_IFIFO    0010000   FIFO
S_ISUID    0004000   set UID bit
S_ISGID    0002000   set-group-ID bit (see below)
S_ISVTX    0001000   sticky bit (see below)
S_IRWXU    00700     mask for file owner permissions
S_IRUSR    00400     owner has read permission
S_IWUSR    00200     owner has write permission
S_IXUSR    00100     owner has execute permission
S_IRWXG    00070     mask for group permissions
S_IRGRP    00040     group has read permission
S_IWGRP    00020     group has write permission
S_IXGRP    00010     group has execute permission
S_IRWXO    00007     mask for permissions for others (not in group)
S_IROTH    00004     others have read permission
S_IWOTH    00002     others have write permission
S_IXOTH    00001     others have execute permission

(Note that the leading 0 means those numbers are octal numbers.)

You can see seven fields in the mode word.

S_IFMT   file type
S_ISUID  set UID bit
S_ISGID  set-group-ID bit
S_ISVTX  sticky bit
S_IRWXU  owner permissions
S_IRWXG  group permissions
S_IRWXO  other permissions

If you view the mode as its fields instead of as a number (0x81B4 = 33204 = 0100664 = 0b1000000110110100), you get:

S_IFMT:  S_IFREG (regular file)
S_ISUID: 0 (no set UID bit)
S_ISGID: 0 (no set-group-ID bit)
S_ISVTX: 0 (no sticky bit)
S_IRWXU: S_IRUSR | S_IWUSR (user has rw)
S_IRWXG: S_IRGRP | S_IWGRP (group has rw)
S_IRWXO: S_IROTH (other has r)

Doing & 0777 is the same as doing as & (S_IRWXU | S_IRWXG | S_IRWXO) which extracts the fields containing the various permission.


$_ is a variable that refers to $main::_. It's set by some constructs (foreach loop, map, grep) and used as the default by many operators (e.g. say; means say $_;).

The elements of @_ are aliased to the parameters passed to the sub being executed. e.g. $_[0] and thus $x contains 4 in sub f { my ($x) = @_; ... } f(4);

于 2013-05-10T03:25:03.273 回答
2
  1. -rw-rw-r-- corresponds to the binary numeral 110110100 (the first - isn't a permission). As we're dealing with groups of three bits, we use octal (which maps groups of three bits to 0-7) for convenience: 644.

  2. To understand the 100 of 100644, man 2 stat.

  3. Regarding:

    printf ("%o\n", $mode & 775); #im not sure about the 775, or is it 577

775 is decimal, not octal. If you want only the last nine bits, then AND the number with octal 777 (= all bits set, binary 111_111_111).

printf "%o\n", 0100664 & 0777;  # 664
于 2013-05-10T03:28:57.357 回答