Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

file command replacement (showing the type of a file with perl)

by pvaldes (Chaplain)
on Apr 17, 2012 at 12:13 UTC ( #965499=perlquestion: print w/ replies, xml ) Need Help??
pvaldes has asked for the wisdom of the Perl Monks concerning the following question:

As everybody surely knows, the "file" command in bash prints info about the type of a file. (i.e file flower.jpg will show that this is a jpeg image)

I'm trying to achieve the same in a perl script. Thus I wrote something like this:

use strict; use File::Type; my $infile = "flower.jpg"; my $ft = File::Type->new(); my $type1 = $ft->checktype_filename($infile); my $type2 = $ft->mime_type($infile); print "$type1\n"; print "$type2\n"; print `file $infile`;

and my proto-script returns

image/jpeg image/jpeg flower.jpg: JPEG image data, JFIF standard 1.01

Thus we have a clear winner, the File::Type module, although not bad, is clearly less accurate that file. And that's the question: żDo you know any way/module/function integrated with perl to obtain the same amount of info about a file? or I need to use system here to call directly the file command?. The big nuisance here is that if you search for file + perl in google you obtain millions of unrelated results

Comment on file command replacement (showing the type of a file with perl)
Select or Download Code
Re: file command replacement (showing the type of a file with perl)
by halfcountplus (Hermit) on Apr 17, 2012 at 12:41 UTC

    the File::Type module, although not bad, is clearly less accurate that file.

    You've misunderstood something. The explicit purpose of File::Type is "to determine the MIME type of that file".

    'image/jpeg' is a valid MIME type. 'JPEG image data, JFIF standard 1.01' is not. MIME types are important, eg, in internet transfers -- your browser decides how to treat something based on the MIME type in the http header.

    The file command (which will give you a mime type too, if you use the --mime switch) can provide more detailed information in a "human readable" form but there is no protocol for this. It looks to me like someone has written a module porting "file" into perl tho: file.

    However, since the author admits "this implementation is significantly slower than the C version" you might be better off just using backticks ;).

Re: file command replacement (showing the type of a file with perl)
by Corion (Pope) on Apr 17, 2012 at 12:44 UTC

    Usually, the file command relies on the "magic" bytes at the start of a file. Usually these signatures are stored in a file named /etc/magic. There are modules that either include such a database or can reuse such a file. Most are found by Magic (resp. MMagic for File::MMagic).

Re: file command replacement (showing the type of a file with perl)
by zwon (Monsignor) on Apr 17, 2012 at 13:26 UTC

    If you want same output as from file have a look at File::LibMagic, it uses the same library:

    $ file 1x1.png 1x1.png: PNG image data, 1 x 1, 8-bit/color RGBA, non-interlaced $ perl -MFile::LibMagic -E'say File::LibMagic->new->describe_filename( +"1x1.png")' PNG image data, 1 x 1, 8-bit/color RGBA, non-interlaced
Re: file command replacement (showing the type of a file with perl)
by pvaldes (Chaplain) on Apr 17, 2012 at 14:04 UTC

    Thank you very much for the replies, specially to halfcountplus for educate me and to Corion for point me (first) to the right trace

    I had tried File::MMagic but without success, it seems that is deprecated and some buggy. This is what you can read about the module in cpan:

    "The currently recommended module in this area seems to be File::LibMagic. Other alternatives include File::Type (gives less useful results)...

    Thus following the trace I finish to arrive to the same module recommmended by Zwon, (thanks also) that works like a charm

    # apt-get install libfile-libmagic-perl # (run this first once if you are in Debian) use File::LibMagic ':easy'; my $infile = $ARGV[0] print MagicFile($infile),"\n"; print `file $infile`;

    Last two lines show basically the same info when we provide a filename as first argument.

    Problem solved thus. Thanks again

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://965499]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (20)
As of 2015-07-02 13:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (40 votes), past polls