Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PERLLIB,PERL5LIB - How to unset inside perl script?

985 views
Skip to first unread message

Ed Kulis

unread,
Jan 2, 2001, 3:47:00 PM1/2/01
to

Hi,

I'd like to unset PERLLIB and PERL5LIB within the perl script so that I
don't get the library mismatch error below.

>name_split.pl
Perl lib version (5.003) doesn't match executable version (5.006)
Compilation failed in require at
/home/vantive7/perl_dir/lib/diagnostics.pm line 5.
BEGIN failed--compilation aborted at
/home/vantive7/perl_dir/lib/diagnostics.pm line 5.
Compilation failed in require at name_split.pl line 42.
BEGIN failed--compilation aborted at name_split.pl line 42.


Our Unix environment is a little wild and I can't trust environment
variables, and I've written Korn shell defender scripts that unset all
non standard Korn shell variables so the environment completely
understood.

So, my problem is solved for Korn shell.

I'd like to run perl scripts without necessarily calling them from a ksh

wrapper.

I've tried 'no lib ' and I've tried deleting paths from @INC but it
seems that the perl script detects the library mismatch at the very
beggining of execution.

I did find the the -T (taint) option did unset the external lib
variables. It's not practical for me to use the -T option because, I'm
training other developers in their first use of perl and they're just
not ready for the rigor of secure programming.

I also don't want to set the libraries explicitly. I want to rely on the

default locations of the libraries implicit from the shebang
#!/usr/local/bin/perl

You might think that I could just unset PERLLIB,PERL5LIB but I'm afraid
that it's not that simple. As we rollout code it ends up in
environments where there are many people trying to "help" by presetting
various variables.

-ed

Bart Lateur

unread,
Jan 2, 2001, 6:22:54 PM1/2/01
to
Ed Kulis wrote:

>I'd like to unset PERLLIB and PERL5LIB within the perl script so that I
>don't get the library mismatch error below.

BEGIN {
delete @ENV{qw(PERLLIB PERL5LIB)}
}

If this does help (one never can be sure...) you could stuff it into a
tiny module (you don't need a separate package, import() or even the
BEGIN block; but you do need a true value at the end) and require it,
maybe even through the commandline:

use NoPerlLib;
or
perl script.pl -MNoPerlLib


I'm sure some purist will object about the language...

--
Bart.

Garry Williams

unread,
Jan 2, 2001, 7:21:17 PM1/2/01
to
On Tue, 02 Jan 2001 23:22:54 GMT, Bart Lateur <bart....@skynet.be>
wrote:

>Ed Kulis wrote:
>
>>I'd like to unset PERLLIB and PERL5LIB within the perl script so that I
>>don't get the library mismatch error below.
>
> BEGIN {
> delete @ENV{qw(PERLLIB PERL5LIB)}
> }

Bzzzt.

[ lines wrapped for posting ]

$ PERL5LIB=some/directory perl \
-wle 'BEGIN{delete @ENV{qw(PERLLIB PERL5LIB)}} print "@INC"'
some/directory /usr/local/lib/perl5/5.6.0/sun4-solaris
/usr/local/lib/perl5/5.6.0
/usr/local/lib/perl5/site_perl/5.6.0/sun4-solaris
/usr/local/lib/perl5/site_perl/5.6.0 /usr/local/lib/perl5/site_perl .
$

>If this does help (one never can be sure...)

Oh, yes one can...

--
Garry Williams

Martien Verbruggen

unread,
Jan 2, 2001, 9:07:58 PM1/2/01
to
On Tue, 02 Jan 2001 12:47:00 -0800,
Ed Kulis <eku...@apple.com> wrote:
>
> I'd like to unset PERLLIB and PERL5LIB within the perl script so that I
> don't get the library mismatch error below.

First of all: I would get rid of those environment variables from the
user's environment, and clean up the environment on your machine. Perl
has the lib pragma to do exactly the opposite of what you're doing.
Maybe you should have a global module that you include in all your
scripts, in which you put the correct 'use lib' lines, or even better,
clean up your perl installations. I run 4 different versions on this
machine, without any problems, use lib lines, or environment variables.

That said:

You could use the lib mpragma, if $ENV{PERL5LIB} only contains one
pathname:

[Lines wrapped for legibility in the following]

$ PERL5LIB=/some/directory; export PERL5LIB
$ perl -wle 'print "@INC"'
/some/directory /opt/perl/lib/5.6.0/i686-linux /opt/perl/lib/5.6.0
/opt/perl/lib/site_perl/5.6.0/i686-linux /opt/perl/lib/site_perl/5.6.0
/opt/perl/lib/site_perl/5.005/i686-linux /opt/perl/lib/site_perl/5.005
/opt/perl/lib/site_perl .
$ perl -wle 'no lib $ENV{PERL5LIB}; print "@INC"'
/opt/perl/lib/5.6.0/i686-linux /opt/perl/lib/5.6.0
/opt/perl/lib/site_perl/5.6.0/i686-linux /opt/perl/lib/site_perl/5.6.0
/opt/perl/lib/site_perl/5.005/i686-linux /opt/perl/lib/site_perl/5.005
/opt/perl/lib/site_perl .

If you have more than one directory in your PERL5LIB, you'll have to
split on ':' and loop, and delete the occurences from @INC yourself:

#!/usr/local/bin/perl -wl
use strict;
use lib; # only needed for the @lib::ORIG_INC variable

BEGIN
{
for my $e (split /:/, $ENV{PERL5LIB})
{
for (my $i = 0; $i < @INC; $i++)
{
splice @INC, $i, 1 if $e eq $INC[$i];
}
}
}

print "@INC\n";
print "@lib::ORIG_INC";

Of course, this last one will also work when there's only one pathname
in PERL5LIB.

To make this more portable, you might need to insert some OS detection
to figure out what the correct character is to split on. On unices, this
is a colon, on other platforms, it may be something else. The
documentation in perlrun states that the separator is always a colon,
but this would make it impossible on DOS-derivatives, VMS and Mac to use
fully qualified pathnames, since the colon is used on those platforms as
part of a fully qualified path.

The perlvms documentation states that the separator is '|'. The
perlwin32 documentation states that it is ';', and I suspect it's the
same on os/2. I don't know what it is on Mac, or whether it exists at
all.

Something like (untested):

unless ($OS = $^O)
{
require Config;
$OS = $Config::Config{'os_name'};
}

for ($OS)
{
/^MS(DOS|Win)/i && do { $sep = ';'; last };
/^OS2/i && do { $sep = ';'; last };
/^VMS/i && do { $sep = '|'; last };
/^MacOS/i && do { $sep = "\0"; last }; # Just guessing
# default
$sep = ':'
}

You may need to insert others. I don't really know.

Now you can split (see above) on $sep:

for my $e (split /\Q$sep/, $ENV{PERL5LIB})

Martien
--
Martien Verbruggen |
Interactive Media Division | Little girls, like butterflies, need
Commercial Dynamics Pty. Ltd. | no excuse - Lazarus Long
NSW, Australia |

Bart Lateur

unread,
Jan 3, 2001, 9:11:32 AM1/3/01
to
Martien Verbruggen wrote:

>$ perl -wle 'no lib $ENV{PERL5LIB}; print "@INC"'

Assuming this works, what about the case where PERL5LIB point to a
directory which is *standard* for searching, for example, the site/lib
or even the standard lib directory? Oops, there go all the standard
modules.

Disallowing PERL5LIB to be set, looks like a better solution to me.

Tell you what, why don't you (generic "you" that one) run all perl
scripts with the -T option. That one makes perl ignore the PERL5LIB and
PERLLIB settings. Amlongst others. See perlrun.

--
Bart.

Abigail

unread,
Jan 3, 2001, 9:20:23 AM1/3/01
to
Martien Verbruggen (mg...@tradingpost.com.au) wrote on MMDCLXXXII
September MCMXCIII in <URL:news:slrn9552b...@martien.heliotrope.home>:
`' On Tue, 02 Jan 2001 12:47:00 -0800,

`' Ed Kulis <eku...@apple.com> wrote:
`' >
`' > I'd like to unset PERLLIB and PERL5LIB within the perl script so that I
`' > don't get the library mismatch error below.
`'
`' First of all: I would get rid of those environment variables from the
`' user's environment, and clean up the environment on your machine. Perl
`' has the lib pragma to do exactly the opposite of what you're doing.
`' Maybe you should have a global module that you include in all your
`' scripts, in which you put the correct 'use lib' lines, or even better,
`' clean up your perl installations. I run 4 different versions on this
`' machine, without any problems, use lib lines, or environment variables.

Well, the lib pragma does its own opposite: no lib LIST;

`' BEGIN


`' {
`' for my $e (split /:/, $ENV{PERL5LIB})
`' {
`' for (my $i = 0; $i < @INC; $i++)
`' {
`' splice @INC, $i, 1 if $e eq $INC[$i];

`' }
`' }
`' }

Eeew. That's a three nested loops (splice needs to loop too).

BEGIN {
my %h = map {$_ => 1} split /:/ => $ENV {PERL5LIB};
@INC = grep {!$h {$_}} @INC;
}

No nested loops.

Abigail
--
:$:=~s:$":Just$&another$&:;$:=~s:
:Perl$"Hacker$&:;chop$:;print$:#:

Martien Verbruggen

unread,
Jan 3, 2001, 5:17:54 PM1/3/01
to
On 3 Jan 2001 14:20:23 GMT,

Abigail <abi...@foad.org> wrote:
> Martien Verbruggen (mg...@tradingpost.com.au) wrote on MMDCLXXXII
> September MCMXCIII in <URL:news:slrn9552b...@martien.heliotrope.home>:
> `' On Tue, 02 Jan 2001 12:47:00 -0800,
> `' Ed Kulis <eku...@apple.com> wrote:
> `' >
> `' > I'd like to unset PERLLIB and PERL5LIB within the perl script so that I
> `' > don't get the library mismatch error below.
> `'
> `' First of all: I would get rid of those environment variables from the
> `' user's environment, and clean up the environment on your machine. Perl
> `' has the lib pragma to do exactly the opposite of what you're doing.
> `' Maybe you should have a global module that you include in all your
> `' scripts, in which you put the correct 'use lib' lines, or even better,
> `' clean up your perl installations. I run 4 different versions on this
> `' machine, without any problems, use lib lines, or environment variables.
>
> Well, the lib pragma does its own opposite: no lib LIST;

Euhmm, you did see my example of doing this with 'no lib' later on in
the article, right? I just was trying to say that I find it odd to first
add stuff to your environment, and then to have to jump through hoops to
remove it again. I'd rather not add it to the environment in the first
place, and include specific instructions in the programs that do need
them, as opposed to adding instructions to the programs that don't need
them. It just seems so... the wrong way around.

> `' BEGIN
> `' {
> `' for my $e (split /:/, $ENV{PERL5LIB})
> `' {
> `' for (my $i = 0; $i < @INC; $i++)
> `' {
> `' splice @INC, $i, 1 if $e eq $INC[$i];
> `' }
> `' }
> `' }
>
> Eeew. That's a three nested loops (splice needs to loop too).
>
> BEGIN {
> my %h = map {$_ => 1} split /:/ => $ENV {PERL5LIB};
> @INC = grep {!$h {$_}} @INC;
> }
>
> No nested loops.

Yep. I thought when I posted it that I should clean it up, but then I
couldn't be bothered anymore :).

Martien
--
Martien Verbruggen |
Interactive Media Division | I took an IQ test and the results
Commercial Dynamics Pty. Ltd. | were negative.
NSW, Australia |

Abigail

unread,
Jan 3, 2001, 7:48:48 PM1/3/01
to
Martien Verbruggen (mg...@tradingpost.com.au) wrote on MMDCLXXXII
September MCMXCIII in <URL:news:slrn95798...@martien.heliotrope.home>:
)) On 3 Jan 2001 14:20:23 GMT,
)) Abigail <abi...@foad.org> wrote:
)) >
)) > Well, the lib pragma does its own opposite: no lib LIST;
))
)) Euhmm, you did see my example of doing this with 'no lib' later on in
)) the article, right?

Eh, no, I had to go back to spot the example (inserting a blank line
between different programs isn't a waste of bandwidth).

However, the BEGIN segment isn't necessary to remove multiple directories
from a $PERL5LIB environment variable.

no lib split /:/ => $ENV {PERL5LIB};

works fine.

Abigail
--
$_ = "\x3C\x3C\x45\x4F\x54" and s/<<EOT/<<EOT/e and print;
Just another Perl Hacker
EOT

The WebDragon

unread,
Jan 3, 2001, 11:35:55 PM1/3/01
to
In article <slrn956d97....@tsathoggua.rlyeh.net>,
abi...@foad.org wrote:

| Abigail
| --
| :$:=~s:$":Just$&another$&:;$:=~s:
| :Perl$"Hacker$&:;chop$:;print$:#:

just curious, but this wouldn't compile until I changed it to this:

;$:=~s:$":Just$&another$&:;$:=~s:


:Perl$"Hacker$&:;chop$:;print$:#:

(only one character changed)

using 5.004 here.. something changed later on to allow that to compile
as it was?

--
send mail to mactech (at) webdragon (dot) net instead of the above address.
this is to prevent spamming. e-mail reply-to's have been altered
to prevent scan software from extracting my address for the purpose
of spamming me, which I hate with a passion bordering on obsession.

Martien Verbruggen

unread,
Jan 4, 2001, 3:20:42 AM1/4/01
to
On 4 Jan 2001 00:48:48 GMT,

Abigail <abi...@foad.org> wrote:
> Martien Verbruggen (mg...@tradingpost.com.au) wrote on MMDCLXXXII
> September MCMXCIII in <URL:news:slrn95798...@martien.heliotrope.home>:
> )) On 3 Jan 2001 14:20:23 GMT,
> )) Abigail <abi...@foad.org> wrote:
> )) >
> )) > Well, the lib pragma does its own opposite: no lib LIST;
> ))
> )) Euhmm, you did see my example of doing this with 'no lib' later on in
> )) the article, right?
>
> Eh, no, I had to go back to spot the example (inserting a blank line
> between different programs isn't a waste of bandwidth).

Nope, you're right, but I just pasted what I had in another xterm.

> However, the BEGIN segment isn't necessary to remove multiple directories
> from a $PERL5LIB environment variable.
>
> no lib split /:/ => $ENV {PERL5LIB};
>
> works fine.

Hmmm.. you're right. I tried

BEGIN { no lib $_ for split /:/, $ENV{PERL5LIB} }

which doesn't work, and then gave up. Just need to be more persistent.

Martien
--
Martien Verbruggen |
Interactive Media Division | If it isn't broken, it doesn't have
Commercial Dynamics Pty. Ltd. | enough features yet.
NSW, Australia |

Martien Verbruggen

unread,
Jan 4, 2001, 3:27:52 AM1/4/01
to
On 4 Jan 2001 04:35:55 GMT,

The WebDragon <nos...@nospam.com> wrote:
> In article <slrn956d97....@tsathoggua.rlyeh.net>,
> abi...@foad.org wrote:
>
> | Abigail
> | --
> | :$:=~s:$":Just$&another$&:;$:=~s:
> | :Perl$"Hacker$&:;chop$:;print$:#:
>
> just curious, but this wouldn't compile until I changed it to this:
>
> ;$:=~s:$":Just$&another$&:;$:=~s:
>:Perl$"Hacker$&:;chop$:;print$:#:
>
> (only one character changed)
>
> using 5.004 here.. something changed later on to allow that to compile
> as it was?

The original works fine for me in perl 5.004_05

$ /opt/perl5.00405/bin/perl -v

This is perl, version 5.004_05 built for i686-linux

[snip]
$ /opt/perl5.00405/bin/perl


:$:=~s:$":Just$&another$&:;$:=~s:
:Perl$"Hacker$&:;chop$:;print$:#:

__END__
Just another Perl Hacker
$

It should be equivalent to something like:

$: =~ s/$"/Just$&another$&/; $: =~ s/\n/Perl$"Hacker$&/;
chop $:; print $:

Maybe empty labels weren't allowed some time before 5.004_05? Any error
messages?

Martien
--
Martien Verbruggen |
Interactive Media Division | Unix is user friendly. It's just
Commercial Dynamics Pty. Ltd. | selective about its friends.
NSW, Australia |

Abigail

unread,
Jan 4, 2001, 3:47:06 AM1/4/01
to
Martien Verbruggen (mg...@tradingpost.com.au) wrote on MMDCLXXXIII
September MCMXCIII in <URL:news:slrn958d0...@martien.heliotrope.home>:
'' On 4 Jan 2001 04:35:55 GMT,


Hint 1: It has nothing to do with labels.
Hint 2: Perl makes exceptions to characters in certain places of a file.
Hint 3: It's explained in the manual.

Abigail
--
sub f{sprintf'%c%s',$_[0],$_[1]}print f(74,f(117,f(115,f(116,f(32,f(97,
f(110,f(111,f(116,f(104,f(0x65,f(114,f(32,f(80,f(101,f(114,f(0x6c,f(32,
f(0x48,f(97,f(99,f(107,f(101,f(114,f(10,q ff)))))))))))))))))))))))))

0 new messages