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
>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.
>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
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 |
>$ 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.
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$:#:
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 |
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
| 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.
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 |
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 |
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)))))))))))))))))))))))))