Edit Perl $PERL5LIB and #INC - perl

I'm using macOS and I just add:
export PERL5LIB=/usr/local/tools/modules/PERL/:$PERL5LIB
And:
export PERL5LIB=/usr/local/tools/modules/PERL/"${PERL5LIB:+:$PERL5LIB}"
And when I do:
echo $PERL5LIB
Or:
perl -e 'print join "\n", #INC;'
It appear two times, I just want to edith both files $PERL5LIB and #INC to eliminate both paths.
How could I do that?

Replace
export PERL5LIB=/usr/local/tools/modules/PERL/:$PERL5LIB
export PERL5LIB=/usr/local/tools/modules/PERL/"${PERL5LIB:+:$PERL5LIB}"
with just
export PERL5LIB=/usr/local/tools/modules/PERL/"${PERL5LIB:+:$PERL5LIB}"
Notes:
There's no real harm to having a directory in #INC twice. (Just a tiny performance penalty.)
You should remove that trailing slash, but it's harmless.
The language is named "Perl. It's not an acronym, so spelling it "PERL" is inappropriate. A better directory name would be perl.

Related

Remove entry from #INC

Is it possible to remove an entry from #INC from the command line?
I know export PERL5LIB=/path/file.pm can be used to add them, but can they be removed in a similar fashion?
EDIT:
I know that directories are not typically removed from #INC, but in my case (and maybe yours, if you are here for help) I added an entry of my own that I needed removed not only because it was a custom entry, but also because it specified a file (incorrect usage of #INC) and not a folder.
Additional Info:
The export command was executed from the command line, not from a script.
You could use the no lib pragma from the command line with perl -M-lib=...:
$ PERL5LIB=/tmp/foo perl -le 'print for #INC'
/tmp/foo
... normal #INC entries ...
$ PERL5LIB=/tmp/foo perl -M-lib=/tmp/foo -le 'print for #INC'
... normal #INC entries ...
Update: Based on the wording of the question, I assumed that you had a system where you had set PERL5LIB, and were asking how to exclude entries once in a while, only for specific runs of perl ("from the command line"). That's what the above does: The effect of no lib used on the command line is only temporary for that run of perl.
But the discussion in the comments revealed that it was the opposite: you had run export PERL5LIB=... "from the command line" (the effect of which is only temporary the current session/shell), and wanted to undo that change - for which the solution is either to run export PERL5LIB= (setting a new value overwrites the previous one, export is not like adding elements to a list, it just sets a new value), or to simply log out and back in again.
If you had set PERL5LIB in a place like the .profile or .bashrc files, then you would need to edit those and comment out or delete the entries you don't want, and log out and back in again.
You can change it in a BEGIN block. Example:
$ perl -MData::Dumper -e 'BEGIN { #INC = qw// }; print Dumper(\#INC);'
$VAR1 = [];

What does perl -I means

I see this a lot in bash scripts and I cannot see this in the manual and other sites.
What does the -I in running a perl script mean?
It is run like this:
perl -I$prod_dir $prod_dir/script.pl <parameter1> <parameter2>
Can someone explain it to me?
-Idirectory
Directories specified by -I are prepended to the search path for modules (#INC ).
Source: perlrun documentation
It means perl will include the modules available under specified directory following -I which is $prod_dir in your case.
By default Perl picks up modules from #INC. If you want to use a module which is not available in #INC then you can specify the directory using -I. This specified directory will be appended to #INC at run time.
Also read:
How is Perl's #INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)
How to change #INC to find Perl modules in non-standard locations

Can't locate XML/XPath.pm in #INC

I have a .pl script in which starts by:
#!/usr/bin/perl
use XML::XPath;
use Getopt::Long;
I can't seem to run that via perl myScript.pl, having this error:
(#INC contains: /usr/share/ /usr/local/lib64/perl5 /usr/local/share/perl5/usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at most_generic_wrapper.pl line 3.
BEGIN failed--compilation aborted at myScript.pl line 3.
1- I tried to locate the XPath.pm file and export that as:
export PERL5LIB=/usr/share/perl5/XML/Twig
and
export PERL5LIB=/usr/share/perl5/XML
2- Installed perl -MCPAN -e 'install XML::Parser'
3- Used -I to explicitly define the path as:
perl -I perl -MCPAN -e 'install XML::Parser' myScript.pl
4- changing the line 3 to use XML::Twig::XPath; led to:
cannot use XML::Twig::XPath: neither XML::XPathEngine 0.09+ nor XML::XPath are available at /usr/share/perl5/XML/Twig/XPath.pm line 11.
BEGIN failed--compilation aborted at /usr/share/perl5/XML/Twig/XPath.pm line 13.`
But none of them solved the issue and I keep receiving the same error at line.3.
P.S: Running on CentOS 6.2 with the kernel 2.6.32-358 and perl --version=v5.10.1 (*) built for x86_64-linux-thread-multi
Any helps would be appreciated,
Your title says XML::XPath can't be found, but your question indicates you tried to install XML::Parser. Did you try to install XML::XPath?
From man perlrun: "If PERL5LIB is not defined, PERLLIB". You seem to have tried setting PERLIB5 (notice the spelling difference: the var is PERL5LIB (or PERLLIB), not PERLIB5).
From man perlrun: "PERL5LIB -- A list of directories in which to look for Perl library files before looking in the standard library and the current directory." You seem to have tried setting it to the full path to a .pm file, rather than a directory.
The file you assigned would be XML::Twig::XPath, not XML::XPath; those are two different Perl modules.
Edit: After looking at your revised question:
I'm not sure if your script requires XML::Twig::XPath or XML::XPath, or if either one can provide the API you need. However, XML::Twig::XPath seems to depend on XML::XPath so you will need XML::XPath no matter what, and it looks like XML::XPath is not installed on your system. I think that's probably the main problem. Please try to install XML::XPath using CPAN.
The value of the PERL5LIB variable (or the argument to the -I option) should be the directory that sits at the base of the package-qualified module file. For example, if XML::XPath is located at ~/perl_custom_modules/XML/XPath.pm, then you need to set PERL5LIB (or the -I argument) to ~/perl_custom_modules. The XML directory is part of the package qualification of the module, so does not need to be included in the include path.

Does the otherlibdirs Configure option rewrite or just modify #INC?

I'm a perl noob and I have a very basic question regarding the #INC post: How is Perl's #INC constructed? (aka What are all the ways of affecting where Perl modules are searched for?)
Does the "otherlibdirs" Configure option completely rewrite the directories that are part of #INC, or merely add another directory? It's not clear to me from that answer what it does, and I don't want to screw up the whole #INC path.
Thanks!
Perusing source of the Perl Configure script, we find the following usage information:
case "$otherlibdirs" in
''|' ') dflt='none' ;;
*) dflt="$otherlibdirs" ;;
esac
$cat <<EOM
Enter a colon-separated set of extra paths to include in perl's #INC
search path, or enter 'none' for no extra paths.
EOM
So if you compile Perl with something like
Configure -Dotherlibdirs=/usr/foo/bar:/usr/foo/bar/baz
Then the directories /usr/foo/bar and /usr/foo/bar/baz will be appended to the normal #INC built-in to the perl binary.

How do I set up Strawberry Perl in MSYS?

I have Strawberry Perl and have msys Perl 5.6 removed.
Now perl will invoke Strawberry (due to PATH env) but how do I map the perl command in .pl or other Perl script files which have #!/bin/perl or #!/usr/bin/perl shebang lines?
I was thinking of making a hardlink to perl.exe in msys/bin or merge the whole Strawberry inside the msys directory, but I'm not sure.
The solution is to create a symlink to the Strawberry Perl executable from within MSYS Tip of the hat to smaudet for his input:
First, remove or rename the Perl executables that the MSYS installation came with, if any (which the OP has already done); e.g.:
mv /usr/bin/perl /usr/bin/perl.msys
mv /usr/bin/cpan /usr/bin/cpan.msys
Then create a symlink to Strawberry Perl's executable in its place:
ln -s /c/strawberry/perl/bin/perl.exe /usr/bin/perl
# Unfortunately, doing the same for `cpan` doesn't work directly, because
# Strawberry Perl's `cpan` executable is a *batch* file, `cpan.bat`, which
# cannot be directly invoked from MSYS.
# To invoke it from MSYS (assuming it is in the %PATH%):
# cmd /c 'cpan.bat ...'
# With an explicit path:
# cmd /c 'c:\strawberry\perl\bin\cpan.bat ...'
#
# Here's how to create a stub script that still allows invocation as
# `cpan`:
echo 'cmd /c "C:\strawberry\perl\bin\cpan.bat $*"'>/usr/bin/cpan && chmod +x /usr/bin/cpan
Once the /usr/bin/perl symlink is in place, existing scripts with shebang lines #!/usr/bin/perl and #!/bin/perl will work again (the latter also works, because /bin and /usr/bin are effectively the same location in MSYS).
Note that scripts written with the more flexible shebang line #!/usr/bin/env perl do not need this, because env will directly find Strawberry Perl's perl.exe in the path.
Some background:
Unix-emulation environments such as MSYS and Cygwin do not respect Windows' %PATHEXT% variable to determine what executable to invoke a (non-binary) file with. In other words: filename extensions have no meaning with respect to execution there.
Instead, they solely go by whether the file has a shebang line:
If there is one, the executable specified in the shebang line is used.
If there is none, the default (POSIX-like) shell /bin/sh is used.
Thus, trying to invoke *.bat or *.cmd files directly fails, because they don't have a Unix shebang line and are therefore executed by /bin/sh rather than cmd.exe.
Unlike in Windows, this also works with (executable) files that have no filename extension at all.
this works beautifully on the windows side of the computer, on the MSYS side you may need to
check the PATH environment variable and fix to include the strawberry perl access path
check the scripts for complete path in the shebang line (#!/usr/bin/perl).
Those paths that are absolute in msys are in fact relative to the msys install directory in windows.
you may need to "plug" your strawberry perl install to match or change the #! line
in the latter case my recommendation would be to use something like: #!env perl that checks the environment for the perl interpreter and alleviate the burden of dealing with /cygdrive/c/my/windows/path/not/visible/from/msys/otherwise
The correct shebang would be, eg. #!"C:/strawberry/perl/bin/perl.exe". However, you might prefer to run scripts explicitly with Perl rather than rely on the shebang, eg. perl script.pl or perl "C:\strawberry\perl\bin\cpan"
Note that Strawberry Perl doesn't get the shebang right for its own scripts, such as cpan and perldoc . Bug reported at https://rt.cpan.org/Public/Bug/Display.html?id=82837