Why is plenv install-cpanm installing to the wrong location? - perl

Something wacky happened with my plenv setup and I haven't gotten my head around it.
plenv install-cpanm
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 297k 100 297k 0 0 1571k 0 --:--:-- --:--:-- --:--:-- 1567k
!
! Can't write to /Library/Perl/5.18 and /usr/local/bin: Installing modules to /Users/olaf/perl5
! To turn off this warning, you have to do one of the following:
! - run me as a root or with --sudo option (to install to /Library/Perl/5.18 and /usr/local/bin)
! - Configure local::lib in your existing shell to set PERL_MM_OPT etc.
! - Install local::lib by running the following commands
!
! cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
!
App::cpanminus is up to date. (1.7042)
$ plenv which cpanm
plenv: cpanm: command not found
$ find /Users/olaf | grep bin/cpanm
/Users/olaf/.cpanm/work/1482416411.97013/App-cpanminus-1.7042/bin/cpanm
/Users/olaf/.cpanm/work/1482416863.23085/App-cpanminus-1.7042/bin/cpanm
/Users/olaf/perl5/bin/cpanm
$ find /Users/olaf/.plenv | grep cpanm
/Users/olaf/.plenv/libexec/plenv-install-cpanm
/Users/olaf/.plenv/plenv.d/rehash/rehash_cpanm.bash
I would expect cpanm to get installed somewhere inside of ~/.plenv, but that's just not happening. I'm guessing something in my dot files/shell setup/$ENV is messed up?
This is what my $ENV looks like:
env | grep PLENV
PLENV_SHELL=bash
Also, the beginning of my PATH is:
PATH=/Users/olaf/.plenv/shims:/Users/olaf/.plenv/bin

I got this sorted with some help from Tatsuhiko Miyagawa. It turns out that I had switched to the system Perl via plenv and had expected it to handle module installs in the same way that it works for Perls which plenv installs for you. The solution was just to choose a version of Perl which I had installed earlier via plenv (plenv local 5.24.0) and then to plenv install-cpanm. Tatsuhiko Miyagawa also pointed out that I'll need to install-cpanm for each version of Perl that I have installed.

Related

Running a Perl script from crontab when you use Perlbrew

I have tried the following and find it to work. This is done with a non-privileged user. First find out where your perl command is:
# which perl
Then check the value of PERL5LIB:
# echo $PERL5LIB
Then, at the crontab file of the user, do something like:
MAILTO=<my email address for the jobs output>
HOME=/home/myhome
PERL5LIB=/home/myhome/perl5/lib/perl5
0 2 * * * $HOME/<rest of path to perl>/perl $HOME/<path to my perl script> arg1 ...
This will run a job at 2am and seems to find all Perl libs correctly. My question is: is this complete and portable? Is there a better way?
I have seen a number of bash and perl scripts out there that are supposed to prepare the environment for the execution of a Perl script, but this seems to suffice. Any advice will be welcome!
EDIT: From the comments to the question, it seems that I am using a "bad" mixture of Perlbrew and local::lib. The way to make sure libraries get installed inside a particular Perlbrew version is answered here: How do I install CPAN modules while using perlbrew?. Both cpan and cpanm will install under PERL5LIB when you are using local::lib unless you explicitly tell them to do otherwise. Also cpanm seems to be better suited to working along with Perlbrew.
The shebang (#!) line of the script should point to the (perlbrew-installed) perl it is meant to run under. (This should be done as part of installing the script.) That's all you need.
0 2 * * * /path/to/script arg1 ...
If you already have multiple perl installations managed with perlbrew the easiest approach is to just use perlbrew exec to run your script. The -q and --with options allow you to silence superfluous output and select the specific version of perl to run the script/job. Try something like:
perlbrew exec perl -E 'say "Hello from $]\n"' (this will show errors from older versions (< 5.10) of perl that don't have the -E switch enabled by default).
perlbrew exec -q --with 5.26.1 perl -E 'say "Hello from $]\n"' (this will run the command and suppress informational output).
perlbrew exec -q --with 5.26.1 perl ~/script_from_heaven.pl (runs the script with the perl version requested).
perlbrew exec -q --with 5.26.1 ~/script_from_heaven.pl (runs the script with the perl version requested or hard-coded in the script's shebang line).
I tend to explicitly set PERL5LIB and use local::lib only when I need them or for certain users or environments where I exclusively install all CPAN modules in $HOME/perl5/lib/perl5 (a full application deployment, say). Otherwise I find running perl from perlbrew pretty convenient.
A couple of things I've found helpful: setting an alias for perlbrew environments that you want to keep stable for a particular use can be a useful way to manage multiple perls:
~/$ perlbrew alias create perl-5.24.0 stable-cronperl
~/$ perlbrew list
perl-5.8.9
perl-5.10.1
perl-5.24.0
cperl-cperl-5.26.1
stable-cronperl (5.24.0)
perl-5.26.1
NB: however the alias is only useful/useable as a stable #! shebang anchor for use at the top of your scripts if you want to make them executable:
#!/home/cronic/perl5/perlbrew/perls/stable-cronperl/bin/perl
You can't refer to an alias using --with for example:
perlbrew exec --with stable-cronperl ~/smart_comments.pl
Reporting this as either a documentation issue or a bug is on my to do list.

Determine if app is Wayland or X client

Is there a way to determine if an arbitrary app is an X client or a Wayland client (or neither) from the command line without fully launching it?
You can run ldd on the binary to check which libraries it links against. If it has "libwayland-client" you're probably looking at a Wayland client. For X you need to look for "libX11" or "libxcb".
To expand on the excellent answer given by #Alexander Sukhoverkhov what needs to be done is:
cd /usr/bin
ldd $application_name | grep wayland
Furthermore, to check which binaries have wayland support you could try:
cd /usr/bin
find . | xargs ldd | grep wayland -B 55
The above is not really very clean but it works. You can further pipe it to a file and then use vim to navigate.
cd /usr/bin
find . | xargs ldd | grep wayland -B 55 >> candidates
vim candidates
# Use vi movement
The -B flag stands for before and helps to print the binary name.

/etc/environment does not work on Solaris 10

GOAL: to pre-inject in Perl's #INC array on a Solaris 10 box with perl version 5.8.4, and that this should be available in any way perl is invoked! That includes ssh non-interactive logins...
So that something like:
ssh my.solaris.10.box 'perl -MSpecialModule -le "print qq/Powerball!\n/"'
Works and does not throw me attitude of Can't locate SpecialModule.pm in #INC (#INC contains: /usr/perl5/5.8.4/lib/i86pc-solaris-64int /usr/perl5/5.8.4/lib /usr/perl5/site_perl/5.8.4/i86pc-solaris-64int /usr/perl5/site_perl/5.8.4 /usr/perl5/site_perl /usr/perl5/vendor_perl/5.8.4/i86pc-solaris-64int /usr/perl5/vendor_perl/5.8.4 /usr/perl5/vendor_perl .).
BEGIN failed--compilation aborted.
So far I tried to add PERLLIB=/path/to/always/include/in/INC:
/etc/environment
/etc/default/init
/etc/bash.bashrc as ssh my.solaris.10.box 'echo $SHELL' gives me SHELL=/bin/bash
~/.ssh/environment of a specific user as in ssh privuser#my.solaris.10.box
Now, /etc/profile works, but only if I'm actually logged in on that box... for my purpose, I wish to execute with ssh non-interactively.
I'm not a SysAdmin, but I'll just share the below:
grep -i pam /etc/ssh/sshd_config | grep -v '^#'
PAMAuthenticationViaKBDInt yes
And adding UsePAM yes did not do the trick.
Any other suggestion, does /etc/default/init require a reboot? Otherwise, /etc/environment works a sold for all my Linux Red Heads...
What can I do to get /etc/environment to work on Solaris 10?
1) Note that Sun used to recommend that you install your own copy of Perl rather than mess around with what's in /usr/perl5.
2) Rename the perl binary to something else, and in its place put a tiny shell script that sets the environment the way you want it and then execs the renamed binary.

Cannot execute system command in cygwin

I have the following simple perl script that I cannot execute in cygwin:
#!/usr/bin/perl
use strict;
system("../cat.exe < a.txt > b.txt");
When I run it, the script tells me:
./my_test.pl
'..' is not recognized as an internal or external command,
operable program or batch file.
However I can run the command in the cygwin shell:
$ ../cat.exe < a.txt > b.txt
$ ../cat.exe b.txt
hello
The executable cat.exe exists in the directory above and a.txt in the current working
directory.
My version of perl:
$ perl -v
This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 12 registered patches, see perl -V for more detail)
You're using a perl built for Windows (ActiveState? Strawberry?), not the Cygwin version. It invokes cmd.exe for system(), which thinks that .. is the command and / introduces an option.
Try changing the the system() call to:
system("..\\cat.exe < a.txt > b.txt");
But you should normally be using the Cygwin version of perl when running a script from bash.
What is the output of the following commands?
echo "$PATH"
type -a perl
/usr/bin/perl -v
From what we've seen so far, it looks like you've installed some Windows-specific Perl with its perl.exe in your Cygwin /usr/bin directory. If so, then (a) uninstall it (you can reinstall it elsewhere if you like), and (b) re-install the "perl" package via Cygwin's setup.exe.
(And add use warnings; after use strict; in your Perl scripts. This isn't related to your problem, but it's good practice.)
The error message obviously comes from cmd.exe, which apparently is your default shell. What does echo $SHELL say? Maybe you need to define that variable to become /bin/bash.exe.

Why won't a module installed by `cpanm` be recognized?

I installed perl-5.12.2 using perlbrew:
perlbrew install perl-5.12.2 -D=usethreads -D=useithreads -D=uselargefiles -f
I then switched to this version and installed IPC::System::Simple using cpanm.
However, when I try to run my script I get:
Can't locate IPC/System/Simple.pm in #INC (#INC contains: /home/dave/workspace/proj1/scripts/bin/../lib /home/dave/src/bioperl-live /home/dave/perl5/perlbrew/perls/perl-5.12.2/lib/site_perl/5.12.2/x86_64-linux-thread-multi /home/dave/perl5/perlbrew/perls/perl-5.12.2/lib/site_perl/5.12.2 /home/dave/perl5/perlbrew/perls/perl-5.12.2/lib/5.12.2/x86_64-linux-thread-multi /home/dave/perl5/perlbrew/perls/perl-5.12.2/lib/5.12.2 .) at /home/dave/workspace/proj1/scripts/bin/../lib/createLayout.pm line 14.
I also found the following dir:
~/perl5/lib/perl5/x86_64-linux-thread-multi/auto/IPC/System/Simple
but it's empty (I have no idea if this means something).
Try this step-by-step guide, paying close attention to steps 7 and 8 (and optionally 9).
What does which cpanm from the command line show? For you it should report:
/home/dave/perl5/perlbrew/bin/cpanm
If thats OK then what does ls -l /home/dave/perl5/perlbrew/bin/cpanm show? It should be pointing to:
cpanm -> /home/dave/perl5/perlbrew/perls/current/bin/cpanm
And finally ls -l /Users/barry/perl5/perlbrew/perls/current should be pointing to the Perl you've switched to in perlbrew:
/home/dave/perl5/perlbrew/perls/current -> perl-5.12.2
All three of these must be like this otherwise something is wrong.
If its not then one likely issue is that cpanm is pointing to another installed Perl. You need to have cpanm installed for each version of perl under perlbrew:
perlbrew switch perl-5.12.2
curl -L http://cpanmin.us | perl - App::cpanminus
Now if which cpanm still doesn't show the perlbrew path then you have a $PATH precedence issue in your .bash_profile (or equivalent) file. This can be fixed by making sure that your perlbrew line...
source /home/dave/perl5/perlbrew/etc/bashrc
... in the profile file is after any other export $PATH lines.
After re-login back in you can confirm that this is right by doing echo $PATH and you should see perlbrew at the beginning (the left) of the path string, ie. something like this:
/home/dave/perl5/perlbrew/bin:/home/dave/perl5/perlbrew/perls/current/bin:/usr/bin:/bin:/usr/local/bin: