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

Hello Monks,

I want to determine a file's type - not in the sense if it is a .pdf, perl file, etc - rather if it is a directory, symlink, etc. I know this is contained in the first bit of the mode returned by stat(). I do not know how to "unpack" that bit and determine what it means.

Could someone kindly shed some light on this for me?

Much thanks

--draconis

  • Comment on How to determine a file's type via stat()

Replies are listed 'Best First'.
Re: How to determine a file's type via stat()
by robartes (Priest) on May 09, 2003 at 17:20 UTC
    This is actually documented in the docs for stat. Basically, you import the S_IF* functions from the Fcntl module:
    use Fcntl ':mode'; print "It's a directory!" if S_IFDIR( (stat($file))[2]);
    For a different way of doing this, have a look at the file test operators in perlfunc.

    CU
    Robartes-

      Thanks, but that is not exactly what I was looking for. I know I can use the file-test operators. What I would like to know if if the first bit of the octal returned by stat for mode will reveal what it really is. So, for instance, if the first bit is a 2 then that means "X".

      I was trying to avoid using the file-test operators if at all possible. If it is not possible then I will proceed with such.

      Any further thoughts?

        I know I can use the file-test operators. What I would like to know if if the first bit of the octal returned by stat for mode will reveal what it really is. So, for instance, if the first bit is a 2 then that means "X".

        Actually, that's what the S_IF* functions do for you. If you want to do this yourself, have a look at the bitshift operators (<< and >>) to do bitwise arithmetic.

        CU
        Robartes-

        draconis,
        robartes has pointed you in the right direction. Read the docs on stat.

        You can import symbolic mode constants (S_IF*) and functions (S_IS*) from the Fcntl module:
        S_IFREG S_IFDIR S_IFLNK S_IFBLK S_ISCHR S_IFIFO S_IFSOCK S_IFWHT S_ENFMT

        Figure the bitwise math out and create a hash lookup.

        Cheers - L~R

Re: How to determine a file's type via stat()
by TVSET (Chaplain) on May 09, 2003 at 17:22 UTC
    I don't think that you can do it with stat, but perldoc -f -X will tell you another simple way to do what you want. In brief:

    my $filename = "/path/to/file"; print "Regular file\n" if (-f $filename); print "Directory\n" if (-d $filename); print "Symlink\n" if (-l $filename); print "Pipe\n" if (-p $filename); print "Sockete\n" if (-S $filename); ...

    Leonid Mamtchenkov aka TVSET

Re: How to determine a file's type via stat()
by shemp (Deacon) on May 09, 2003 at 17:25 UTC
    there is detailed info on stat() at http://www.perldoc.com/perl5.6.1/pod/func/stat.html

    summary: in array context, it returns a 13 element array. element 2 is what you want to examine. I.E.
    my @stat_info = stat($filename); my $file_mode = $stat_info[2]; ... # or my $file_mode = (stat($filename))[2]; my $file_type = S_IFMT($file_mode)
    file type is still just a bit string, but see the bottom of the above linked page for how to interpret those bits.
Re: How to determine a file's type via stat()
by cbro (Pilgrim) on May 09, 2003 at 17:33 UTC
    stat will return a 13 element array. Element 2 is file mode (type and permissions).
    If, however, you are aware of the type that the file should be...just use the file test operators:
    -f, plain file
    -d, directory
    -l, symbolic link
    etc...
    HTH, Chris
    Update: Well, while I was looking away...everybody already said this. Sorry for the repetition.
Re: How to determine a file's type via stat()
by draconis (Scribe) on May 09, 2003 at 17:34 UTC
    Thanks to all !!!

    I "get it" now. (the light bulb turns on - and all you hear is the clicking and clacking of keys)