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

Hello!

When running in a browser a Perls script having this line:

use Digest::MD5::File qw(file_md5_base64 file_md5_hex file_md5 md5 md5_hex md5_base64);

It fails with:

Can't locate Digest/MD5/File.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at test.cgi line 6.

When I run the same script in SSH as root, all is going fine.

locate Digest/MD5/File.pm returns:

/root/.cpan/build/Digest-MD5-File-0.08-mgchoT/blib/lib/Digest/MD5/File.pm

/root/perl5/lib/perl5/Digest/MD5/File.pm

I added:

use lib '/root/perl5/lib/perl5/Digest/MD5/File.pm';

in the script in case, same thing, fails.

Any help would be appreciated, thank you!

Replies are listed 'Best First'.
Re: "Cannot find location"
by shmem (Chancellor) on Apr 01, 2017 at 09:34 UTC
    When running in a browser

    Surely you mean: when running in a web server? There's no browser I am aware of which is able to run perl scripts (i.e. has an embedded perl.)

    The system user which runs the web server surely has no access to /root on a well behaved system. /root is an utterly inappropriate place to install modules meant to be used system wide.

    Consider installing them in a world readable place. Run perl -V:sitelib to find out where perl expects local modules to be.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: "Cannot find location"
by kcott (Archbishop) on Apr 01, 2017 at 09:43 UTC

    G'day natol44,

    Whatever Perl you're using for your browser script is not the same as the one you used when installing Digest::MD5::File.

    If you run these two, you'll see different @INC lists:

    /path/to/browser/perl -V /path/to/root/perl -V

    You should install Digest::MD5::File using the /path/to/browser/perl environment.

    Consider whether you should be modifying the 'root' Perl at all. Doing so is generally a bad idea. I don't know what OS you're using; however, the 'root' Perl is typically part of the OS and often has specific patches such that it works in a way expected by the OS. Adding a new module may seem harmless enough, but it might have dependencies which may be automatically installed, overwriting the version expected by the OS. Take a look at Perlbrew as an alternative way of handling this.

    The lib pragma failed due to incorrect usage: it does not take paths to modules as arguments - see the linked doco for details. Using this pragma is just a band-aid solution which I don't recommend: if you go down this path, you'll likely end up with multiple 'use lib ...' statements, in multiple scripts, and a potential maintenance nightmare. Install the module correctly once - do nothing else!

    — Ken

      Whatever Perl you're using for your browser script is not the same as the one you used when installing Digest::MD5::File.

      Not necessarily, /root/perl5/lib/perl5 makes it look like OP used local::lib under root to install the module. shmem already noted some of the problems with that, although I agree with your advice not to modify the system Perl, at least not with cpan or cpanm - using the system's package manager is usually okay.

Re: "Cannot find location"
by haukex (Archbishop) on Apr 01, 2017 at 12:27 UTC

    If this happens to be a Debian-based system, you could install the module via sudo apt-get install libdigest-md5-file-perl. Using local::lib, as you appear to have done, might be possible too, as long as you install the modules in a location that the webserver can access, i.e. not /root. We'd need to know more about your server set-up to give you better advice though.

    If all this gets too complicated, then note that Digest::MD5::File appears to be a convenience wrapper around the core module Digest::MD5, which you could use instead.

Re: "Cannot find location"
by duyet (Friar) on Apr 01, 2017 at 09:24 UTC
    or you can add it to your @INC path:
    BEGIN { push @INC, '/root/perl5/lib/perl5'; } use Digest::MD5::File qw(file_md5_base64 file_md5_hex file_md5 md5 md5 +_hex md5_base64);
      or you can add it to your @INC path:
      BEGIN { push @INC, '/root/perl5/lib/perl5'; }

      That's nearly exactly what use lib does: See lib. (use lib unshifts, i.e. the extra directory is searched first, not last.)

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: "Cannot find location"
by Anonymous Monk on Apr 01, 2017 at 07:06 UTC
    use lib '/root/perl5/lib/perl5';
      Same thing: Can't locate Digest/MD5/File.pm in @INC (@INC contains: /root/perl5/lib/perl5 /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at test.cgi line 9.
        Same thing: Can't locate Digest/MD5/File.pm in @INC (@INC contains: /root/perl5/lib/perl5 ...

        I guess you have a Perl version lower than 5.18:

        When require encounters an unreadable file, it now dies. It used to ignore the file and continue searching the directories in @INC [perl #113422].
        # Perl 5.10 $ perl -I/root -MTesting Can't locate Testing.pm in @INC (@INC contains: /root ... # Perl 5.24 $ perl -I/root -MTesting Can't locate Testing.pm: /root/Testing.pm: Permission denied.
Re: "Cannot find location"
by natol44 (Sexton) on Apr 02, 2017 at 19:03 UTC
    Well, I solved it finally: Uninstalled Digest::MD5::File using cpanplus (that I installed for this!), then reinstalled the perl module through the Webmin interface! The fist time I used cpan directly from SSH.. And so now it works! Thank you everybody for your help!
Re: "Cannot find location"
by natol44 (Sexton) on Apr 02, 2017 at 17:08 UTC
    Thank you for your replies, I will answer here to all!

    1- I am using Centos-7 (64 bits) with Webmin and Virtualmin panels.

    2- I added BEGIN { push @INC, '/root/perl5/lib/perl5';} and it did not change anything, the same message is returned saying, it seems that this "push" is not considered.

    3- Haukex, you told me to use Digest::MD5 instead of Digest::MD5::File. I do not understand, as Digest::MD5 is properly installed and works fine, but it does not include the functions I am using. Only Digest::MD5::File includes. If I remove the "::File" line I get this error when running the script:

    Can't locate object method "addpath" via package "Digest::MD5"

    Script section:
    my $md5 = Digest::MD5->new;
    $md5->addpath($longfile);
    my $digest = $md5->hexdigest;
    my $digest = file_md5_hex($longfile);
    End of Script section

    4- You tell me to install "correctly" the module. So my 2 questions are 1- How to UNinstall it (from the bad location) and 2- How to install it correctly, using CPAN or yum?


    As you probably noticed I am really not an expert ;)

    Thank you!
      Digest::MD5 ... does not include the functions I am using. ... If I remove the "::File" line I get this error...

      I didn't mean that Digest::MD5 is a drop-in replacement for Digest::MD5::File, sorry for the misunderstanding. You would need to use Digest::MD5 according to its documented API. (Digest::MD5::File appears to monkey-patch its functions into Digest::MD5, which probably just adds to the confusion.) For example, here's how you might replace the module's file_md5_hex function:

      use Digest::MD5; sub file_md5_hex { my $filename = shift; open my $fh, '<:raw', $filename or die "open $filename: $!"; my $md5 = Digest::MD5->new->addfile($fh); close $fh; return $md5->hexdigest; }