hhoffman has asked for the wisdom of the Perl Monks concerning the following question:


I'm trying to take the mode of stat($filename)[2] and convert it to "normal" Unix file permissions.
Something like:

$mode = stat($filename)[2]; $unixmode = $mode ?some magic here?

Right now I can only print it (as per the example). Any help would be greatly appreciated.


Comment on converting stat() $mode to unix file permissions
Select or Download Code
Re: converting stat() $mode to unix file permissions
by BrowserUk (Pope) on Jan 25, 2004 at 16:08 UTC
    printf '%o', (stat $filename)[2] & 07777; # Updated: Thanks to [duff] $unixmode = (stat $filename)[2] & 07777; # Updated. One too few 7s.

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Timing (and a little luck) are everything!

      I think perhaps he'd want to use a bit mask of 07777 instead of 0777 so that he could get the set*id bits. In fact, I think there's even an example in perldoc -f stat that shows exactly this.

      Note that in the example, the $unixmode will come out in decimal mode. You may therefore prefer to use the following code to convert the output to the more common octal format:

      $unixmode = sprintf("04%o", (stat $filename)[2] & 07777)
Re: converting stat() $mode to unix file permissions
by Zaxo (Archbishop) on Jan 25, 2004 at 19:49 UTC

    Depending on what you're doing, you may want lstat rather than stat. lstat does not follow symlinks, but instead gives information on the link itself.

    The upper bits aren't as magic as they may seem - they tell the file type. From man 2 stat:

    The following flags are defined for the st_mode field:

    S_IFMT     0170000   bitmask for the file type bitfields
    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 GID 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 permisson
    S_IXOTH      00001   others have execute permission

    The set GID bit (S_ISGID) has several special uses: For a directory
    it indicates that BSD semantics is to be used for that directory:
    files created there inherit their group ID from the directory, not
    from the effective gid of the creating process, and directories
    created there will also get the S_ISGID bit set. For a file that
    does not have the group execution bit (S_IXGRP) set, it indicates
    mandatory file/record locking.

    The `sticky' bit (S_ISVTX) on a directory means that a file in that
    directory can be renamed or deleted only by the owner of the file,
    by the owner of the directory, and by root.
    To make those constants portable and available by name in perl, use Fcntl ':mode';

    After Compline,