Reputation: 1358
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 @_?
Upvotes: 2
Views: 925
Reputation: 385764
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);
Upvotes: 6
Reputation: 5619
-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.
To understand the 100 of 100644, man 2 stat
.
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
Upvotes: 2