September 2011 Archives

Shebangs with perlbrew aliases and EUMM (and without local::lib)

I wanted to comment on kevin spencer's perlbrew intro but my blabbering grew so long I chose to make a separate post instead.


I used to use the #!/usr/bin/env perl trick for shebangs until (when reading about packaging executables with dists) I learned that ExtUtils::MakeMaker (and Module::Build) will automatically rewrite a full-path shebang to point to the interpreter used during install, but it specifically does not do this with the env trick.

I inadvertently combined 'env perl' with local::lib once and found that the script (reachable from my local::lib bin/) would die because I was trying to run a script in my path with a perl that didn't have that module installed (I must have switched perls in the meantime).

If the perl that installed the module is embedded in the script then calling it from the command line makes sure that it will be run by a perl that has the module installed (and has the same version that corresponds to the script using it). So it seems better to me to use the full path and let EUMM rewrite it.

tl;dr: use perlbrew alias to denote "current" version

I typically use one perl as my main perl and use a perlbrew alias to point to it:

perlbrew alias create perl-5.14.1 local

Then I can use


for the shebang in all of my scripts.

Yeah, it's a little long, but I tab complete it or dump an env var rather than typing it out. This way any scripts that are part of dists I release will get rewritten by EUMM upon install and any scripts that are just for my personal use work with my "current" favorite perl.

When 5.14.2 is released I will install it, reinstall the modules I use, and change my perlbrew alias to point to it.

Sometimes I also symlink /usr/local/bin/perl to my perlbrew alias if I'm the only one on the machine or if perlbrew is in a location that is available to everyone (like /opt).

Then you can use the very common


which is shorter and easier to remember.

perlbrew and cpan modules

As a side note I do a perlbrew switch and use the cpan client to install modules directly into the perl lib dir (with the default installdirs site option) and I only use local::lib if I need to test a module with my system-provided perl.

That way (with modules installed relative to the perl that installed them) when you perlbrew switch if you haven't installed a module it's script won't even be found in your path.

If anyone has any points of contention or better suggestions, please share.

About Randy Stauner

user-pic perl -C -E 'say"i \x{2764} ",($^X =~ m#([^/]+)$#)'