How to set correct perl path - perl

I have 2 versions of perl installed. perl v5.18.2 and v5.20.0 . But when I do perl -v I get perl v5.18.2. I don't need v5.18.2 at all. I need v5.20.0. How do I change the path to include v5.20.0 and not v5.18.2?
Here is my $PATH:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
v5.18.2 is installed at /usr/bin/perl and /usr/bin/perl5.18.2, and v5.20.0 at /root/perl5/perlbrew/perls/perl-5.20.0/bin/perl.

See the perlbrew documentation:
switch Permanently use the specified perl as default
perlbrew switch perl-5.20.0
If you haven't already, you will need to add source /root/perl5/perlbrew/etc/bashrc to your login script for this to work.

The following will add the desired build of Perl to the search path so that it's found first:
export PATH="/root/perl5/perlbrew/perls/perl-5.20.0/bin:$PATH"
You may add that to your login script to make this change permanent.
Note that you'll need to update the shebang (#!) lines of scripts installed with a different perl to the following:
#!/root/perl5/perlbrew/perls/perl-5.20.0/bin/perl

It looks like you have three copies of perl installed, as neither of the paths you mentioned are in the PATH variable yet your shell still finds one
There's no need for perlbrew. All you need to do is set your PATH variable on the command line
$ export PATH=/usr/bin/perl5.18.2:$PATH
If you want to make that change permanent then add the command to your profile file at ~/.profile

Related

Unable to execute Perl script unless Perl is inserted before script name

Running Lubuntu -
Beginner Perl programmer
Script is XXX.pl located at ~/projects/XXX/XXX.pl
First line is the shebang
#!/usr/bin/perl
Permission to run is set to Anyone.
In directory ~/projects/XXX, the command
~/projects/XXX$ perl XXX.pl
works as desired, but the command
~/projects/XXX$ XXX.pl
Fails with XXX.pl: command not found
What am I missing ?
The two usual options to execute your Perl script are:
perl XXX.pl
or
./XXX.pl
Both ways assume that your current working directory contains the script XXX.pl, otherwise it won't work.
As already pointed out by jm666 in the comments, you can usually not execute a program or script from your current working directory without prepending ./, primarily because of security reasons. Now, you may wonder why it's necessary.
Explanation:
Your shell uses the contents of an environment variable called $PATH to find out about where external commands (non-builtin programs) are located in your filesystem. If you want to see what's in $PATH, just type the following in your shell:
echo $PATH
Now you can see that the $PATH variable does NOT contain your current working directory. The consequence is that your shell is not able to find the program XXX.pl. By prepending ./ you instruct the shell to execute the program which comes after.
But there are two requirements if you want to execute your Perl script with ./script.pl:
The script has to be executable (check with ls -l)
The first line (shebang line) has to be #!/path/to/your/perl because your shell needs that information to find the perl interpreter in order to run your script
However, #1 and #2 are NOT required when you execute your script with
perl XXX.pl
because it invokes the perl interpreter directly with your script.
See how to make Perl scripts executable on Linux and make the script itself directly executable with chmod for some more details.
Can the script be found?
Is . in your path? If it's not, add it to your path, or use ./XXX.pl instead of XXX.pl.
Can the script be executed?
Do you have execute permission to the file? Fix using chmod u+x XXX.pl.
Is the interpreter correct?
which perl will tell you which interpreter is used when you use perl XXX.pl. That's the path that should be on your shebang (#!) line.

How can i run perl script from anywhere in unix environment?

I have this perl script that I need to distribute to my coworkers who want to run the script from anywhere in the unix environment. What can I do on my part to make running this PERL script easy for them? For example, they can just have the PERL script somewhere in their directory and run just typing
./xyz.pl ttt.conf
with no path declared (like /home/abc/bin/ddd/xyz.pl ttt.conf).
The way I used to do it is add a "bin" directory in your home directory, and add it to the $PATH variable.. then you can add any script you want to use to that directory.
I am no longer familiar with the exact syntax, but something like:
in .bashrc:
$PATH = ( $PATH , $HOME/bin )
Then place the script in /home/user/bin (assuming $HOME == /home/user). When you reload the shell, it will be usable like any normal command/program.
ETA: See robert's comment below on syntax. Also, to allow your co-workers to use a script of yours, you can simply use a hard-coded path, such as /home/patrick/bin.
Put the script in /usr/local/bin (or anywhere else in $PATH). Your sysadmin may have to help you.
The technique I use is:
#!/usr/bin/env perl
This is a common way of getting the command interpreter to find Perl without either (a) moving the file, or (b) declaring the explicit path for Perl in the shebang.
It's mentioned under portability at: http://en.wikipedia.org/wiki/Shebang_(Unix)
You all are kind of right... but that perl script can sit in your path till the cows come home... and it ain't gonna run... until you set the executable bit....
:bin localadmin$ ./perlextip
-bash: ./perlextip: Permission denied
:bin localadmin$ chmod +x perlextip
:bin localadmin$ ./perlextip
Exit 0! Yeehaw.
Also, it should be noted that it need not be IN your path.... You can just call it by the full path, preceeded with a period and a slash, to execute it..
:/ localadmin$ ./ServiceData/UNIX/bin/extip
Exit 0! Yeehaw.
You can also create an alias for such a command in your ~/.bash_profile, or the such, which will let you make a system-wide shortcut of sorts, and you can even throw in a sudo, or the like, if you were so inclined... Then just call that "extip" by name anywhere, you'll be prompted for a password and, all will be well in the world.
alias extip='sudo ./ServiceData/UNIX/bin/extip'

Setting PERL5LIB

Can I set PERL5LIB in a separate script and call that script in other scripts? How do I do it? And how would it affect the script in which it is used?
Setting PERL5LIB at runtime will not affect Perl's search path. You need to export the variable before executing the interpreter.
Alternatively you can modify #INC at compile time (also possible to do in a separate script/module):
BEGIN { unshift #INC, "/path/to/dir" }
This is what the lib pragma does.
You'd do this via 'use lib' rather than manipulating the environment:
use lib '/home/perl5';
That could be in a separate file that you 'require' in.
PERL5INC is a shell environment variable, so you wouldn't set it inside your Perl program (normally) but instead specify it before invoking Perl. The below is a shell command where I've used PERL5LIB to instruct prove to find a Perl module residing in ~/OnePop:
$ PERL5LIB=~/OnePop prove -l t
... PERL5LIB is unset here ....
When a command is preceded by a variable assignment like this, the shell sets and exports the variable (PERL5LIB) to that command, but after that the variable will be unset again. You can also set the variable in the shell, so that all subsequent commands will inherit it.
$ export PERL5LIB=~/OnePop
...
$ prove -l t
... PERL5LIB continues to be set here ...
If you forget the export keyword in the above example (i.e. assigns the value using PERL5LIB=~/OnePop on a separate line) the variable will be set in the shell, but it will not be inherited by any commands you run (meaning that prove will not be able to see it).
Finally, if you wanted to set the environment PERL5LIB variable from inside a Perl program you'd have to write it like this:
$ENV{PERL5LIB} = glob("~/OnePop"); # glob() expands the tilde
system(qw( prove -l t ));
Though, as other have pointed out, if you want to specify the include path from inside Perl it is easier/better to use use lib $PATH.
PERL5INC is an environment variable. Environment variables are only inherited from parents to their children and can't (easily) be set the other way around. If you want to store extra search paths in an external file I suggest you make it a simple list of paths and write a simple loop to read each path from the file and manipulate #INC in the current process. If you want this to be done early at compile time you'll have to use a BEGIN {} block.
For example
BEGIN{
open(INCFILE,"<","my.inc.file") or die($!);
foreach(<INCFILE>){
push #INC,$_;
}
close(INCFILE);
}
Alternative to PERL5LIB:
You could instead install the latest version of Perl 5 available (in a non-system location, of course). After you have used a module file or done whatever is necessary to make the new perl and cpan executables visible to your shell, you can use cpan to install all the modules you need. I have sometimes done this for individual applications in a similar vein to using Python Virtual Environments.

How do I fix "bash: perl myscript.pl: command not found"?

Maybe it's dumbest question in the world, but I seriously have problems with it and could use help. I am trying to run perl script on linux. It's a simple text editing script, nothing fancy. I googled for it and I found that I had to chmod +x it and then just run myscript.pl in the console. Since it's supposed to modify a text file I did myscript.pl > myfile.txt after chmoding it
But it doesn't work. I get: bash: perl myscript.pl: command not found
Unless myscript.pl is in your path you will need to specify the current directory.
$ ./myscript.pl
You can check if the current directory is in your path with $ echo $PATH. If you're frequently using this script you can put it in the path by moving it to a directory that's part of your path, usually ~/bin.
Or by adding the current directory to the $PATH environment variable. Check the documentation for your shell for instructions.
Can you post the first few lines of your script?
Specifically, if you have #!/usr/bin/perl are there any typos on that line, extra spaces, etc.?
Also do a ls /usr/bin/perl (or whatever is on that line) to make sure it's actually there.
It doesn't look like perl is installed on your Linux machine. Do you get the same thing when you try this: # perl -e 'print "hi";' ?
As Chirael said, it sounds like your shebang line (the directive at the top of the file, that tells the shell how to run the script) is invalid somehow. You can bypass the shebang line entirely by invoking your script as:
perl myscript.pl > myfile.txt
You also don't need to set the script's executable bit, as with this method of invocation, you are only reading the script, not executing it (from the shell's perspective).
According to this thread, it could be from different representation of the new line.
Have you written the script on a windows box and copied over to your linux box?
What is your text editor?
I had the same issue, and traced it to DOS line endings (^M). Running dos2unix on the .pl file fixed the issue.
Please use,
./myperl.pl > outfile.txt
to give the current directory path
thanks

How can I install CPAN modules locally without root access (DynaLoader.pm line 229 error)?

Doesn't work with other modules, but to give an example. I installed Text::CSV_XS with a CPAN setting:
'makepl_arg' => q[PREFIX=~/lib],
When I try running a test.pl script:
$ perl test.pl
#!/usr/bin/perl
use lib "/homes/foobar/lib/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi";
use Text::CSV_XS;
print "test";
I get
Can't load '/homes/foobar/lib/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/Text/CSV_XS/CSV_XS.so' for module Text::CSV_XS: /homes/foobar/lib/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/Text/CSV_XS/CSV_XS.so: cannot open shared object file: No such file or directory at /www/common/perl/lib/5.8.2/i686-linux/DynaLoader.pm line 229.
at test.pl line 6
Compilation failed in require at test.pl line 6.
BEGIN failed--compilation aborted at test.pl line 6.
I traced the error back to DynaLoader.pm it happens at this line:
# Many dynamic extension loading problems will appear to come from
# this section of code: XYZ failed at line 123 of DynaLoader.pm.
# Often these errors are actually occurring in the initialisation
# C code of the extension XS file. Perl reports the error as being
# in this perl code simply because this was the last perl code
# it executed.
my $libref = dl_load_file($file, $module->dl_load_flags) or
croak("Can't load '$file' for module $module: ".dl_error());
CSV_XS.so exists in the above directory
When you installed the module, did you watch the output? Where did it say it installed the module? Look in lib. Do you see the next directory you expect?
Look in ~/lib to see where eveything ended up to verify that you have the right directory name in your use lib statement:
% find ~/lib -name CSV_XS.so
Once you see where it is installed, use that directory name in your use lib (or PERL5LIB or whatever).
I expect you have a lib/lib in there somehow. The PREFIX is just the, well, prefix, and the installer appends other directory portions to that base path. That includes lib, man, bin, etc.
Personally I would suggest to use local::lib. :)
Try this instead:
'makepl_arg' => q[PREFIX=~/]
PREFIX sets the base for all the directories you will be installing into (bin, lib, and so forth.)
You may also be running into shell expansion problems with your '~'. You can try to expand it yourself:
'makepl_arg' => q[PREFIX=/home/users/foobar]
It would also be helpful if you included the commands you used to get the error you are asking about.
It looks from the error message ("at /www/common ...") that your script is a CGI or mod_perl script. The web server is probably not running as the user 'foo', under whose home directory you've installed the module - that could result in the web server being unable to read that directory.
It may also be running in a "chroot jail", which would mean that the directory in which you've installed the module may not be visible to the script.
In other words, just because you can see the module, does not mean that the web server, and therefore your script, can do so. You should check the relevant file permissions, and if the server is chrooted, whether your module directory is mounted within the virtual file system.
Does the file in question (CSV_XS.so) exist?
Does it exist at the listed location?
If you do:
set |grep PERL
What is the output?
Have you successfully installed other local perl modules?
I strongly suggest installing your own perl in your own home directory, if you have space. Then you can keep everything under your control and keep your own module set, as well as escaping if the admins are keeping you on an older version of perl. (Not to mention preserving yourself if they upgrade some day and leave out all the modules you are relying on.)