How to use a perl module? - perl

I have installed PAR from CPAN. Now, how do you use it? It gives usage example as:
% pp -o hello hello.pl
How do you use this on Windows? pp gives "command not found".
I am new to perl. Only thing I need is to run a module.

pp isn't a module, it is an application. You need to figure out where it was installed to (I don't know which perl you are using or how you installed it) and use the full path to it.

You should look in your lib directory to ensure that the pp.pm file exists somewhere. then, you can load it up by typing use Par::pp; at the perl command line (i'm guessing that it is part of PAR based on what i've found, it could be something as simple as use pp; at the command line).
once the module is loaded, it should provide the pp command for you to use.
thanks,
mark

Related

Can't update #INC with export PERL5LIB

I'm trying to add the HTML::Entities module path to #INC. I did export PERL5LIB=/mypath/HTML/ followed by source ~/.bashrc. That path is reflected in PERL5LIB, but not in #INC. Is there an additional step that I'm missing?
I'm using perl 5.26.2 on CentOS6.5
Edit:
I (wrongly) assumed that my path wasn't being added to #INC because when I run my perl script I get
Can't locate HTML/Entities.pm in #INC (you may need to install the HTML::Entities module)
(#INC contains:
/home/hek/anaconda3/bin/aux/lib/perl5
/home/hek/anaconda3/lib/site_perl/5.26.2/x86_64-linux-thread-multi
/home/hek/anaconda3/lib/site_perl/5.26.2
/home/hek/anaconda3/lib/5.26.2/x86_64-linux-thread-multi
/home/hek/anaconda3/lib/5.26.2
)
(Line breaks added for readability)
But it does appear below
echo $PERL5LIB
/opt/rh/devtoolset-2/root//usr/lib64/perl5/vendor_perl:/opt/rh/devtoolset-2/root/usr/lib/perl5:/opt/rh/devtoolset-2/root//usr/share/perl5/vendor_perl:/opt/perl/lib/site_perl/5.14.2/x86_64-linux-thread-multi/HTML/
perl -e 'use Data::Dumper; print Dumper(\#INC), "\n"'
$VAR1 = [
'/opt/rh/devtoolset-2/root//usr/lib64/perl5/vendor_perl',
'/opt/rh/devtoolset-2/root/usr/lib/perl5',
'/opt/rh/devtoolset-2/root//usr/share/perl5/vendor_perl',
'/opt/perl/lib/site_perl/5.14.2/x86_64-linux-thread-multi/HTML/',
'/home/hek/anaconda3/lib/site_perl/5.26.2/x86_64-linux-thread-multi',
'/home/hek/anaconda3/lib/site_perl/5.26.2',
'/home/hek/anaconda3/lib/5.26.2/x86_64-linux-thread-multi',
'/home/hek/anaconda3/lib/5.26.2',
'.'
];
Why would there be this discrepency?
I do have multiple versions of perl installed, but which perl returns the version that I need to use, ~/anaconda3/bin/perl.
I tried changing the shebang in my script from #!/usr/bin/env perl to #!/~/anaconda3/bin/perl, but that didn't help.
Two possibilities:
Either the PERL5LIB env var wasn't set in the parent of the perl process giving the error (e.g. you launched it from a web server), or
The -T command line switch was provided to perl process giving the error (since this causes PERL5LIB to be ignored).
In either case, you can use use lib in the source instead of PERL5LIB.
use HTML::Entities looks for a file HTML/Entities.pm in the directories in #INC. No such path is found because it's looking for ones like /opt/perl/lib/site_perl/5.14.2/x86_64-linux-thread-multi/HTML/HTML/Entities.pm.
Leave off the HTML/ part in the directory you're trying to add to the search path and you might have better luck.
Edit: There's still the version mismatch, but as long as the module is pure Perl without any XS components I don't think that will be a big problem. Still better to get it in the right path for the version of perl you're actually using. Do that and you shouldn't have to manipulate the search path at all.
This is to summarize the problems and state what seems to be the simplest solution.
From the output of your test one-liner it is clear that a module installed under v5.14.2 is used in a program meant to run under v5.26.2. That is not good, even if it happens to work.
So install HTML::Entities under the perl build that needs it, v5.26.2.
That also solves the problem you are asking about, since then you won't have to muck about with PERL5LIB or anything else.
Further, the #INC in your one-liner test clearly isn't loaded in your real run, just as you suspected. Possible reasons are given in ikegami's answer, as well as the solution, to use lib "...";. But then you need to use the module version installed for v5.26.2, and once you installed it with that perl there'll actually be no need to specify extra library paths.
Finally, if you end up needing to add that path for some reason, leave off the HTML (last) directory, as Shawn's answer indicates. With use HTML::Entities the directory HTML will be searched (for Entities.pm file) and you only need to provide the directory that contains it.

Perl - Use lib with perl module which have dependencies

I have a Perl script which uses the module Net::SSH::Any. Since it does not belong to the “default” Perl installation, I have to use the use lib functionality to include it in my script.
Now, I have the directory c:\lib\net\ssh\any\ on my drive and I specify this: use lib c:/lib; at the beginning of my script.
It “works”: it didn’t say that the module is missing but it says that it couldn’t locate auto/Net/SSH2/autosplit.ix and at the end no backend available at...
When I add the auto directory (containing the correct structure) in the c:\lib\ directory and launch the script, I get this error:
No backend available at...
Which is an internal error of Net::SSH::Any mentioning it could not access the backend directory (which is already included :/)
Does anyone know how to solve something like that? I hope I was clear enough.
You need to use Local::Lib.
This will let you install and load a whole bunch of libraries and their dependencies in an alternate location. I use cpanm to manage my modules and a command something like this (which I put in a wrapper script).
cpanm -L $cpandir $M --no-skip-installed
Where $cpandir is your locallibdir and $M is the module you are trying to install.
Then in your code you would specify
use local::lib '~/foo';
However, I recommend setting a PERL5LIB environment variable, which will append your custom location to #INC and make the extra use local::lib line unnecessary. You would typically edit .bashrc or .profile in your home directory with a line like:
export PERL5LIB=/home/myusername/mymods/
The issue was caused by the fact that the module was downloaded and installed on a 32bits windows but I tried to run it on a perl 64bits installation! So the Net::SSH2 required module couldn't be executed properly.
To resume:
-How to detect the issue: by executing this command: (thanks to Salva)
"perl -Ic:\lib -MNet::SSH2 -e1"
-Modules definitions in my script:
use lib 'c:\lib';

Running Perl Script from Command Line?

I have perl express 2.5 loaded on my server. I would like to be able to run my perl scripts using a command line so they can be scheduled rather than manually bringing up the script in Perl Express and clicking on the run command. Is there a way to execute the script from a command line using this version of Perl or do I need to download a newer or more robust version of the Perl Engine.
You need to export the Perl interpreter (usually named perl) to your path. Then you can simply do
perl path/to/script.pl
In UNIX-based systems you are also able to run the scripts directly if you prepend
#!/usr/bin/perl
to the scripts and give them executable permissions (you might need to replace /usr/bin/perl with the path to your Perl interpreter).
According to the documentation:
Perl Express is not tied to a specific Perl port and should work with any build for Windows.
and the system requirements:
Windows 98/Me/2000/XP/2003, Perl Interpreter
So you, presumably, have a separate Perl distribution already installed somewhere. That should have a perl.exe executable that you can use to run your script.
You just need to give perl command and the path of your perl script.
example :
D:\Project\dir>perl <path_of_perl_script .pl>

DynaLoader seeing wrong values in #INC

I have multiple versions of Perl installed; each under a different directory. e.g. C:\Perl\5.x.y. I switch between them in a shell by setting PERL5LIB and altering my PATH so that only one version is visible at a time. Normally, this works fine, but when trying to run the version of pp (PAR::Packer) installed under 5.10.1 I have problems loading XS components. parll2nc.exe complains:
This application has failed to start because perl512.dll was not found...
I set PERL_DL_DEBUG and see the following when DynaLoader initializes:
DynaLoader.pm loaded (C:/Perl/5.10.1/site/lib C:/Perl/5.12.1/lib ., \lib)
The stuff before the comma is #INC. The first entry is correct, the second is not. I can't figure out how DynaLoader is getting a 5.12 lib path as running perl directly shows what I would expect:
C:\>perl -e "print join ' ', #INC"
C:/Perl/5.10.1/site/lib C:/Perl/5.10.1/lib .
How is DynaLoader picking up the wrong path and how do I prevent it from doing so?
Similar to the approach I suggested for this question, put a trace on #INC and see when it gets updated.
At the very top of your script, before any other use statements, put:
use Tie::Trace;
BEGIN { Tie::Trace::watch #INC };
Then you will get a warning message when another module edits your #INC array.
I figured it out. The problem is caused by an interaction of several things:
I have *.pl files associated with perl.exe (for the most recent version of Perl installed -- 5.12.1).
I have ".PL" in my PATHEXT environment variable so that I can run Perl scripts without typing the extension. e.g. C:\>foo instead of C:\>foo.pl
My installation of the pp utility does not have a batch file wrapper created with pl2bat. (I'm not sure why.)
The net result is that when I ran pp #myconfig it effectively did this:
C:\Perl\5.12.1\bin\perl.exe C:\Perl\5.10.1\site\bin\pp.pl #myconfig
i.e. it ran the version of pp.pl in my path using the version of perl associated with *.pl files, not the version of perl in my PATH. Thus the mix of libs in #INC between what came from the executable (C:\Perl\5.12.1\lib) and what came from the PERL5LIB environment variable (C:\Perl\5.10.1\site\lib).
The solution is to either run pp as perl pp.pl or (better, because you don't have to remember anything) to create a batch wrapper. Assuming that .BAT is in PATHEXT before .PL, when you type pp Windows will run pp.bat instead of pp.pl, and pp.bat invokes perl (using the version in your path).
sigh

How can I modify my cygwin environment to use Strawberry Perl instead of the packaged Perl distribution?

I currently use Strawberry Perl as my primary Perl distribution. However, I have some applications that make Perl calls through cygwin. These generally fail because they are calling the version of Perl that was packaged with cygwin, and only looking in cygwin's lib folders. How can I modify my cygwin environment to call Strawberry Perl (and use the C:/strawberry/perl/lib dirs) instead?
If you remove Perl from cygwin using the setup program it will use Strawberry Perl by default.
If you are unable to remove Perl from cygwin, you can create a symbolic link to the Perl executable from Strawberry.
From a cygwin shell, use the following set of commands:
$ mv /usr/bin/perl /usr/bin/perl-cygwin
$ ln -s /cygdrive/c/strawberry/perl/bin/perl.exe /usr/bin/perl
This is assuming you used the default Strawberry Perl installer. Update your perl.exe location accordingly if you have it installed somewhere else.
Check to make sure the link is working properly by checking the Perl version:
$ perl -v
It should say This is perl, (version) built for MSWin32-x86-multi-thread (or similar) and not built for cygwin-thread-multi-64int.
You can change your PATH to put the Strawberry directories first. Strawberry tries to be nice by putting its directories at the end of the PATH. If you installed from the .zip file, however, it didn't change the PATH at all.
You could move /usr/bin/perl, but that's a bad idea since it breaks when cygwin tries to update what it thinks is its perl. I just had that happen to me this week and used to happen to me on my Mac until I stopped playing with the system setup and installed my own stuff completely separate.
One good thing I can add is that if you get the right perl to come first in the path, it should handle site-specific CPAN modules you may have installed with strawberry perl running in a CMD shell.
"which perl" is your friend.
If you had trouble with this, you could set the PERL5LIB environment variable, but it shouldn't be necessary.
I still pass in DOS-style file paths as parameters into the perl script, i.e. "d:\data\myfile.txt", not "/cygdrive/d/data/myfile.txt". So oddly enough, this mix of path notation works:
bash> /cygdrive/d/scripts/myscript.pl d:\data\myfile.txt
Many of these are good solutions, but I rather take an easy one that I don't have to modify more than once.
All you need to do is add/modify a line in your .bashrc file.
# Prepend strawberry perl to cygwin's path
export PATH=/cygdrive/C/Tools/Perl/perl/bin:$PATH
source .bashrc file from your shell, (or start a new shell) and run your program.
source ~/.bashrc
perl script.pl
This is probably not a preferred solution, but you should be able to modify the #! line:
#!/cygdrive/c/strawberry/perl/bin/perl5.10.0
I always refer to an explicit location and installation of perl, rather than relying on what is in /usr/bin.
I have two scripts that I use to modify the first line of Perl scripts to whichever Perl is first in my path: rightperl hardcodes to the Perl that is first in my $PATH now, envperl will change the line to #!/usr/bin/env perl so the Perl to use is only picked at the time the script is invoked. Works really well under Cygwin (and from a Unix shell in general).
If you don't want to mess around with any paths or do anything permanent there is an easy TEMPORARY hack. Type "where perl" at Cygwin sh prompt. It will list all the Perl.exe it sees in PATH in their order of execution. Change the names of the ones you don't want to be seen that get listed before the perl you want to use. But DO remember to change them back when you are done or you might have a few problems down the road.
I don't have my cygwin machine nearby so I can't test this, but perhaps you can front-end the perl command with a script: go to /bin under cygwin and move the perl.exe there to something else like perl-org.exe, then set up a shell script that execs your other perl with the same arguments.