http://www.perlmonks.org?node_id=1200044


in reply to When modules install in perl5

Note that the shebang line ("#!...") specifies which perl binary should get executed when the script is run from the command line via /path/to/script.pl (and in a few other cases). Different perl binaries usually have completely different module installation directories, i.e. completely different sets of @INC. You can see the @INC directories with the commands perl -V or perl -le 'print for @INC', and you'll see that typically, none of those are actually under /usr/bin/perl (although there might theoretically be some exotic installations where that's not true).

I'm a little unclear on whether your question is about two different installations of Perl, each with their own sets of modules, or whether it is about a single Perl installation that you want to add another module directory to. It sounds to me like it's the latter, but just in case I'll briefly talk about the former first.

If you use a shebang line of "#!/usr/bin/env perl", as I usually do, then the env tool will use whatever perl comes first in your PATH environment variable, which is the same thing as your shell would do when you type perl script.pl at the command line. So then it's only a matter of managing the PATH variable, which users would normally do in their ~/.profile or equivalent. Users can also install their own entire version of perl (usually into their home directories) manually or using tools such as perlbrew or plenv, which will then take care of managing the different installations. However, when scripts get run by a webserver, the server will typically set up its own environment, including its own PATH. This means this method may not work for CGI scripts - I've found that when you want a script to use a specific installation of Perl, it's usually easiest to hardcode that into the shebang line, i.e. "#!/absolute/path/to/perl" - note how I'm using an absolute path there. This will usually make sure that a webserver will run the script with that perl binary.

How would you do it if some "use xxx" are in /usr/bin/perl, and some in the second folder?

Two different installations of Perl would typically not share modules, and this is a good idea because modules compiled for different versions of Perl will often be incompatible! If you want the same modules available in both Perls, it's best to install them to both.

Now, as for a single installation of Perl with different module installation directories, there are several ways to tell Perl where to look for modules aside from the default locations it was compiled with, in other words, how to modify @INC.

So which one should you use? Often, lib is easiest, unless you have a lot of scripts that you need to modify, and/or you have installed a bunch of modules into one central location that all of your scripts need access to. I've found that usually, PERL5LIB is easiest for "global" changes, since setting environment variables can also be limited to a per-user basis if desired, and you can usually configure your webserver to supply additional environment variables to CGI scripts. The things to be careful about is that if there are multiple places in the system that set PERL5LIB, that they don't clobber each others' changes, and if you have multiple Perl installations, that you don't accidentally point the currently used Perl at the modules for a different version!

Note that it is also possible for users to install modules into their home directories. In this case, they can use perl -I..., PERL5LIB, and lib to configure Perl to look for modules in their directories. There are also tools to make this easier, such as local::lib.

Sorry, I don't know much about suexec - if you're having a problem there, please post a more specific error message with instructions how to reproduce. As for permissions, your CGI scripts would typically have 0755, but that's not required for modules (*.pm files), there 0644 is enough.

Update: I don't think this is the source of your problems, but for the sake of completeness, note that @INC used to include the current working directory ".", but as of Perl v5.26 it does not. (Also made a few more very minor ninja edits.)

Update 2: Although I'm going a bit overkill on the "for the sake of completeness", here is a new thread on using FindBin for library paths that are always in the same place relative to the location of the script file. (Also added the sentence about not clobbering the env var.)

Replies are listed 'Best First'.
Re^2: When modules install in perl5
by snax (Hermit) on Sep 25, 2017 at 16:39 UTC
    The way I read this question, the PERL5LIB environment variable should be the way to go, and perhaps be the very first thing to try. Just append the user-specific local library folder to the existing value, if it's already set.

      All is well. It finds the scipts in the second folder whilst the paths to full installation stays at "urs/bin/perl", so it must have auto undated the path to folder when CPAN installed

Re^2: When modules install in perl5
by cristofayre (Sexton) on Sep 26, 2017 at 16:42 UTC

    Gosh. Thanks for the long reply.

    It's actually one installation of PERL on the shared server, but when a user uses the cPanel to install a "private" module, (such as PDF::AP12) it gets places within a "perl/perl5" of that user.

    On cpanel instructions, it says use "usr/bin/perl" or "usr/bin/perlml"

    But it's academic. The script finds my installed modules within the other folder, and works fine. (Mind you, I didn't help the situation by unloading the files as DOS! Whereas "Filezilla" will auto correct, appears cpanel Filemanager does not!) (Now tring to find a way to recognise the CRLF at the end of scripts

    I used "File::Find::Rule" to reiterate through all the *.pl files on the server, then chmod to set to 705. Can't believe it took less than a second to go through 200+ files in numerous sub domains to set them all! (I mention it as I'm NOW writing a script to open first line of files, check end, and if wrong, THEN open the entire file, do substitute, and resave ... if I can get grep to recognise the \n\r !!