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

I need a way to override the Win 32 environment variable PER5LIB. I use just plain old perl.exe (no Apache) called in a command window initiated by a c program (actually a Windows service) system call. The trouble is, the environment I'm working in has corporate spyware from Oracle called OEMAgent which, every time it robo-updates itself sets global system environment variable PERL5LIB to its own internal copy of Perl (which doesn't have all the lovely modules I need and also can't be touched & manipulated by me.) Any way I can protect myself from this problem by modifying my .pl scripts? I'm still using Perl 5.8.0, unfortunately, and that won't be able to be changed in the very near future.
  • Comment on Need way to override PERL5LIB from inside pl script file

Replies are listed 'Best First'.
Re: Need way to override PERL5LIB from inside pl script file
by choroba (Cardinal) on Jun 24, 2015 at 22:02 UTC
    PERL5LIB is called @INC inside the code. You need to change it as soon as possible, i.e. somewhere need the very top of your script in a BEGIN block:
    BEGIN { @INC = '/path/to/my/libs' }

    See @INC and perlmod.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Need way to override PERL5LIB from inside pl script file
by syphilis (Archbishop) on Jun 25, 2015 at 02:40 UTC
    ... sets global system environment variable PERL5LIB to its own internal copy of Perl

    This is not normally a problem as PERL5LIB does *not* clobber existing @INC.
    It merely adds (prepends)the specified path(s) to @INC:
    C:\>perl -le "print \"@INC\"" C:/MinGW/perl516/site/lib C:/MinGW/perl516/lib . C:\>set PERL5LIB=C:/rubbish C:\>perl -le "print \"@INC\"" C:/rubbish C:/MinGW/perl516/site/lib C:/MinGW/perl516/lib . C:\>
    Seems to me that @INC should still be locating your modules, even though some additional paths have bee prepended to it by PERL5LIB.

    Are you sure you've diagnosed the problem correctly ?
    I'm wondering whether, perhaps, the wrong perl (ie Oracle's perl) is actually running your perl script.

    Cheers,
    Rob
      PERL5LIB does *not* clobber existing @INC. It merely adds (prepends) the specified path(s) to @INC
      Seems to me that @INC should still be locating your modules, even though some additional paths have bee prepended to it by PERL5LIB.

      This is exactly the problem. The Oracle perl library path is prepended to the non-Oracle perl library path. That means that all modules will be loaded from Oracle's perl, and only if they do not exist there, they will be loaded from the non-Oracle perl. No problem for custom modules installed somewhere in in the non-Oracle library path. For pure-perl modules, this should be no big thing, too. But XS modules will likely cause trouble due to mixing perl versions. Also note that pragmatic modules will be loaded from the wrong perl version. That may also cause trouble due to different internals.

      The only in-perl solution is to clean up @INC before loading any module, including pragma modules. This could happen in a BEGIN block at the top of the perl script. Of course, that BEGIN block could also be implicit, as in use. With a module name that does not exist anywhere in the Oracle perl library path, that module would be loaded from the non-Oracle librariy path. Example:

      File GetRidOfOracle.pm somewhere in the non-Oracle perl library path:

      package GetRidOfOracle; # @INC is messed up, so we must not load any other module here. # This includes "strict" and "warnings". sub isOracleDirectory { my $dirname=shift; # We are on Windows. / and \ are equal. Case does not matter. # Change to local conditions as needed. $dirname=~tr|\\|/|; return lc($dirname)=~m|/oracle/|; } # remove Oracle Directories from @INC: @INC=grep { !isOracleDirectory($_) } @INC; 1;

      Any perl script that may suffer from Oracle's PERL5LIB:

      #!/usr/bin/perl # ^- Change perl path and parameters as needed use GetRidOfOracle; # <-- must be the very first command in the script +! use v5.12; use strict; use warnings; # your code here ... # For a demo, set PERL5LIB as Oracle would do, then run this script. # No Oracle directory should be printed as long as GetRidOfOracle is l +oaded. say for @INC;

      Update:

      I just remembered that the OP uses perl 5.8.0, so the demo won't work. Use this for 5.8.0:

      #!/usr/bin/perl # ^- Change perl path and parameters as needed use GetRidOfOracle; # <-- must be the very first command in the script +! use strict; use warnings; # your code here ... # For a demo, set PERL5LIB as Oracle would do, then run this script. # No Oracle directory should be printed as long as GetRidOfOracle is l +oaded. print "$_\n" for @INC;

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Need way to override PERL5LIB from inside pl script file
by afoken (Chancellor) on Jun 24, 2015 at 23:32 UTC

    Call perl.exe via a helper script that explicitly deletes PERL5LIB from the environment. A simple three-line batch file may be sufficient:

    @echo off SET PERL5LIB= perl yourscript.pl

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Yes, this approach may be handy if you have hundreds of Perl scripts, and don't want to edit them all:

      @echo off SETLOCAL SET PERL5LIB= @C:\Path to your perl\bin\perl.exe %*
      Note that I (gutlessly) added SETLOCAL so that changes to PERL5LIB apply for the running of your BAT file only and so cannot interfere with Oracle Perl scripts that depend on the global value of PERL5LIB.

Re: Need way to override PERL5LIB from inside pl script file
by MidLifeXis (Monsignor) on Jun 25, 2015 at 13:14 UTC

    If I thought it would make any difference, I would also suggest filing a defect with Oracle. Of course, that is assuming that the global setting is due to Oracle's install and not your IT department's implementation of a rollout.

    --MidLifeXis

Re: Need way to override PERL5LIB from inside pl script file
by Anonymous Monk on Jun 25, 2015 at 06:29 UTC

    Hmm, lets go hunting [perldoc://PERL5LIB] PERL5LIB -> PERL5LIB

    Oh wow, the docs for PERL5LIB don't explain they modify @INC

    but they do mention use lib which does mention @INC, so not a complete lack of information

    That doc could use an update :)

      Well, that doc does say:

      A list of directories in which to look for Perl library files before looking in the standard library and the current directory.

      I guess it maybe wrongly assumes that the reader can translate "the standard library and the current directory" to mean @INC, but it does say explicitly what happens to @INC when you set PERL5LIB ...

      Probably could be clarified by adding a sentence stating that @INC will be modified by setting this environment variable.

      You can make the change to the docs yourself and get it into the next release of Perl, by forking, editing and making a pull request on GitHub ...

        but it does say explicitly what happens to @INC when you set PERL5LIB ...

        under PERL5LIB @INC isn't mentioned at all, so I don't know what you're talking about

        You can make the change to the docs yourself and get it into the next release of Perl, by forking, editing and making a pull request on GitHub ...

        You too, duh :)