How to use perlbrew with zsh or bash?

bash, perl, perlbrew, zsh

Solution

TL;DR: Your `env` is unusable by perlbrew, and needs to be fixed.

Details: I had the same issue, where running `perlbrew switch ...` spawned a bare bash shell. But I found this was because it was in the same session where I had installed perlbrew. Though I had added it to .bash_profile, I had not sourced `~/perl5/perlbrew/etc/bashrc` in my current shell. (Side note: this was exasperated by using `screen`, and so my session persisted between disconnects.)

As far as I can tell, `perlbrew` distinguishes between two scenarios:

- It already has the environment it needs; i.e., you have sourced `~/perl5/perlbrew/etc/bashrc`

- In this case, `perlbrew switch ...` automagically points `perl` to the version specified. No subshell is spawned. This persists between logouts.

- You have a bare shell, or an environment otherwise unusable by `perlbrew` (e.g., ~/perl5/perlbrew/etc/bashrc` has not been sourced).

- Since it cannot run in the current environment, `perlbrew` throws its hands up, and spawns a new subshell. This is when it executes the `--norc` code you found, and uses a bare shell into which it populates its own environment variables.

- Note that this scenario may also occur in scripts. See Perlbrew in Shell Scripts for more information.

Why would the project want to spawn a bare shell in Senario #2? Yeah, that's a good question, but the more I've thought about it, I'm sure they had their reasons. My current take on this is that `perlbrew` is looking out for itself at this point. Your environment, presumably configured by your rc, was unusable. In a pathological case, perhaps it unset all of the environment variables it needs. Regardless, the subshell logic is a pretty bullet-proof way to make sure `perlbrew` will run as it needs.

One last note - if putting `source ~/perl5/perlbrew/etc/bashrc` into `.bash_profile` meant creating a new file, then your .bashrc may need to be explicitly sourced from that file, as `.profile` may no longer do it:

$ head -3 .profile
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.

Problem

Now I'm really confused about `perlbrew`... In `perlbrew.pm` I see the following: ``` if ($shell =~ /\/zsh\d?$/) { $shell_opt = "-d -f"; # <snip> } elsif ($shell =~ /\/bash$/) { $shell_opt = "--noprofile --norc"; } ``` AFAICT, those settings for `$shell_opt` mean that, at least if invoked from `zsh` or `bash`, `perlbrew use ...` will `exec`a new shell, suppressing the sourcing of all of the user's rc-type files. I really have a hard time envisioning why anyone would want to work in a bare shell. What am I missing here? Is `perlbrew` meant for a use pattern different from standard interaction via a shell? Or is it simply not intended for users of `zsh` or `bash`? EDIT: Just to clarify, in order for me to use one of the `perl`s installed by `perlbrew` I'd have to run something like ``` % perlbrew use perl-5.16.3 ``` When one does so, the code shown above gets run, and as a result `perlbrew` `exec`'s a new shell, with no rc-files. I don't see the point of working in an instance of my shell without my usual rc-files.

Original source