Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

@INC error

by worstead (Acolyte)
on Jan 15, 2020 at 16:46 UTC ( [id://11111445]=perlquestion: print w/replies, xml ) Need Help??

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

I have an error that says I do not have "Mailer.pm" in @INC:
Can't locate Mail/Mailer.pm in @INC (you may need to install the Mail: +:Mailer module) (@INC contains: /usr/local/lib64/perl5/5.30 /usr/loca +l/share/perl5/5.30 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vend +or_perl /usr/lib64/perl5 /usr/share/perl5) at /home/jrayner/CRON/emai +l-reminder-2.0.pl line 62.
yet when I list @INC with
!/usr/bin/env perl # lookinc - where to look for modules $"="\n"; print "@INC\n";
it is there in /usr/local/share/perl5/Mail:
/home/jrayner/perl5/lib/perl5/x86_64-linux-thread-multi /home/jrayner/perl5/lib/perl5 /home/jrayner/perl5/lib/perl5/x86_64-linux-thread-multi /home/jrayner/perl5/lib/perl5 /usr/local/share/perl5/Mail /usr/local/lib64/perl5/5.30 /usr/local/share/perl5/5.30 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5
Where's my error?

Replies are listed 'Best First'.
Re: @INC error
by hippo (Bishop) on Jan 15, 2020 at 16:49 UTC
    I have an error that says I do not have "Mailer.pm" in @INC

    Not quite - it says that you do not have 'Mail/Mailer.pm' in @INC. As there is no 'Mail/Mailer.pm' in /usr/local/share/perl5/Mail it will not find it there. Repalce that entry in @INC with the correct one: /usr/local/share/perl5 and you will probably have more luck.

Re: @INC error
by haukex (Archbishop) on Jan 15, 2020 at 17:37 UTC

    According to your Perl script that prints @INC, you appear to be using local::lib, but those paths (/home/jrayner/perl5/lib/perl5/...) don't appear in the error message, so those two runs of perl are different. Since your script appears to be called ~/CRON/email-reminder-2.0.pl, note that cron does not provide a full environment to the code it runs, so if you want perl scripts run from cron to pick up on the modules you've installed in a nonstandard location, one way to do that is to explicitly set the PERL5LIB environment variable in your crontab file. I'd also recommend always using absolute pathnames for everything in your crontab, including the perl binary.

    Or, you could point PERL5LIB at /usr/local/share/perl5/, as hippo pointed out. I'm a little confused as to how the module ended up there though - your standard @INC paths contains /usr/local/share/perl5/5.30, so going by that the module should have been installed to /usr/local/share/perl5/5.30/Mail/Mailer.pm. Are you using the standard installation procedures for the modules (the system package manager, or e.g. cpanm) or are you doing something custom?

Re: @INC error
by ikegami (Patriarch) on Jan 17, 2020 at 00:40 UTC

    It's true that /usr/local/share/perl5/Mail is the location of Mailer.pm, but Perl isn't looking for Mailer.pm; Perl is looking for Mail/Mailer.pm. /usr/local/share/perl5 needs be added to @INC.

      Tried that. "/usr/local/share/perl5/Mail" there but still get same error.
      melisa:~/CRON$ ./print-INC.pl /home/jrayner/perl5/lib/perl5/x86_64-linux-thread-multi /home/jrayner/perl5/lib/perl5 /home/jrayner/perl5/lib/perl5/x86_64-linux-thread-multi /home/jrayner/perl5/lib/perl5 /home/jrayner/perl5/lib/perl5/x86_64-linux-thread-multi /home/jrayner/perl5/lib/perl5 /usr/local/share/perl5/Mail /usr/local/lib64/perl5/5.30 /usr/local/share/perl5/5.30 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5
      error
      Can't locate Mail/Mailer.pm in @INC (you may need to install the Mail: +:Mailer module) (@INC contains: /usr/local/lib64/perl5/5.30 /usr/loca +l/share/perl5/5.30 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vend +or_perl /usr/lib64/perl5 /usr/share/perl5) at /home/jrayner/CRON/emai +l-reminder-2.0.pl line 62. BEGIN failed--compilation aborted at /home/jrayner/CRON/email-reminder +-2.0.pl line 62.
      The program "email-reminder-2.0.pl" appears to run correctly when called independently but not when called by cron.
        Tried that.

        I think it'd be best if you showed us exactly what you tried, because the output you're showing here just shows that some of the entries in @INC got duplicated, not that the path /usr/local/share/perl5 got added to @INC like we suggested. And as I said, in cron, you'll have to set up the environment variables yourself. If you could explain more about your setup (like whether you're actually using local::lib or not, and how the module ended up where it did, what commands you're actually trying, etc.), we could be of more help.

        The program "email-reminder-2.0.pl" appears to run correctly when called independently but not when called by cron.

        It therefore seems that a different @INC is being used when cron runs the script.
        The error message plainly states that @INC is:
        /usr/local/lib64/perl5/5.30 /usr/local/share/perl5/5.30 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5
        If /usr/local/share/perl5/Mail/Mailer.pm exists, then @INC needs to include /usr/local/share/perl5.
        But /usr/local/share/perl5 is not one of the locations specified in @INC when cron runs the script.

        Cheers,
        Rob

        huh, /usr/local/share/perl5 is still not in @INC. (No idea what the first list you posted is, but it's not in that either.)

        Tried that. "/usr/local/share/perl5/Mail" there but still get same error.

        It doesn't look like it


        melisa:~/CRON$ ./print-INC.pl
        /home/jrayner/perl5/lib/perl5/x86_64-linux-thread-multi
        /home/jrayner/perl5/lib/perl5
        /home/jrayner/perl5/lib/perl5/x86_64-linux-thread-multi
        /home/jrayner/perl5/lib/perl5
        /home/jrayner/perl5/lib/perl5/x86_64-linux-thread-multi
        /home/jrayner/perl5/lib/perl5
        /usr/local/share/perl5/Mail
        /usr/local/lib64/perl5/5.30
        /usr/local/share/perl5/5.30
        /usr/lib64/perl5/vendor_perl
        /usr/share/perl5/vendor_perl
        /usr/lib64/perl5
        /usr/share/perl5

        ##</code><code>##

        Can't locate Mail/Mailer.pm in @INC (you may need to install the Mail::Mailer module) (@INC contains: /usr/local/lib64/perl5/5.30 /usr/local/share/perl5/5.30 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5) at /home/jrayner/CRON/email-reminder-2.0.pl line 62.
        BEGIN failed--compilation aborted at /home/jrayner/CRON/email-reminder-2.0.pl line 62.
Re: @INC error
by talexb (Chancellor) on Jan 17, 2020 at 19:53 UTC

    Works for me ..

    $ perl -e 'print join("\n",@INC)' | xargs -I % find % -name Mailer.pm find: ‘/usr/local/lib/x86_64-linux-gnu/perl/5.24.1’: No such file or d +irectory find: ‘/usr/local/share/perl/5.24.1’: No such file or directory /usr/share/perl5/Mail/Mailer.pm
    As has already been pointed out, all you've found is a Mail directory. That directory may or may not have a Mailer.pm in it.

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

      Thank you all for your help. Clearly my Perl installation is a mess. The agility of my memory has deteriorated since I began programming in assembly language in in the 1950s. I have also become lazy. I use Fedora (currently 31) and have relied on upgrading instead of new installations. As a result the various additions and even separate installations of Perl that I have made over the years still exist on my hard drive, I probably went to cpan as a user as well as root. In addition, I have various additions to @INC in .bashrc and /etc/profile whose purpose I have forgotten. Over ten years ago I was installing Perl from a tarball because Fedora did not include PerlMagick.

      My question now is how can I remove all versions of Perl and start with a completely new version including the necessary additions to @INC? Using "dnf remove" or "rpm -e" will only remove my latest version (i.e. perl-5.30.1-449.fc31.x86_64). As a last resort I could completely reinstall Fedora but that would take a long time considering the number of additional programs I have installed and the tweaks I have made.

        My question now is how can I remove all versions of Perl and start with a completely new version including the necessary additions to @INC?

        Well, you don't necessarily need to remove the old versions to build a fresh, self-contained Perl. In any case, you first need to hunt down and eliminate all environment variables related to Perl. In particular, look in your ~/.profile and ~/.bashrc, but environment variables could also be set elsewhere (like some files under /etc, depending on the system). Look for anything Perl-related, including for example source ~/perl5/perlbrew/etc/bashrc. Those would be in particular PERL5LIB, any PATH entries pointing to any specific Perl builds, PERL_MB_OPT, PERL_MM_OPT, PERL5OPT, and really any other environment variables with PERL in the name (see perlrun). If you're unsure about any of these, feel free to ask here.

        Then, it depends on whether it's enough to install Perl in your home directory, or whether you want to install it in some system-wide location. For the former, I'd suggest perlbrew. You can clobber ~/perl5/perlbrew/ first if you want to make sure you're getting a fresh start. Of course, if the file permissions on ~/perl5/perlbrew/ allow it, then you can use this Perl on the entire system.

        If you wanted to build Perl from source into some global location, like say /opt, then have a look at the INSTALL file. In short, it can be as simple as doing the following in the Perl source directory: sh Configure -de -Dprefix='/opt/perl5.30' && make && make test && sudo make install.

        Both of the methods above will set up self-contained Perl builds, that is, their @INC directories will only be located below ~/perl5/perlbrew/perls/perl-*/ or /opt/perl5.30, respectively, instead of being spread out all over the system. You can freely install modules there, and you no longer need to worry about @INC, PERL5LIB, local::lib, and so on. You only need to worry about your PATH pointing to the installation of Perl you want to use, or pointing your shebang line at the correct Perl.

        For installing modules, I strongly recommend cpanm, which you can install via curl -L https://cpanmin.us | perl - App::cpanminus (see App::cpanminus). When you're installing modules, you can check which perl and which cpanm to make sure they are from the same installation, otherwise you've got something strange going on with your PATH.

        If the installation gets mucked up somehow, you can simply perlbrew uninstall or rm -rf /opt/perl5.30 to clobber them. Keeping a cpanfile with your dependencies is an advantage, since it allows easy re-installation of your modules with "cpanm --installdeps .".

        Then, in your crontab file, make sure to call the correct Perl, I recommend doing this with the absolute pathname. So for example, 0 0 * * *  /opt/perl5.30/bin/perl /home/user/script.pl arg1 arg2 ....

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-19 05:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found