简体   繁体   中英

How to use perlbrew with zsh or bash?

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 'sa 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.

No idea why it's like that, but that code is not normally executed. You have to explicitly execute the perlbrew binary to reach that code from bash. But the use and switch features (which call the sub containing the quoted code) are normally handled by the perlbrew shell function.

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:

  1. It already has the environment it needs; ie, 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.
  2. You have a bare shell, or an environment otherwise unusable by perlbrew (eg, ~/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.

Edit

Don't mind me: I didn't realise that the spawned shell was used interactively.


A program running in a shell that has sourced its rc-files is stuck with whatever those rc-files do. In a pathological case, a .bashrc might alias echo to rm -rf , causing the random deletion of some unfortunately-named files and directories (and filling the console or logfile with garbage errors). perlbrew.pm needs to run some commands through a shell, and is taking care to ensure that it doesn't accidentally nuke anything because some rc-file had something weird in it.

No human user would want to work without their rc-files. Humans, however, can compensate for how their personal setup differs from the norm. perlbrew cannot.

You need to source the perlbrew rc file in your script to set up the paths without launching a sub-shell.

From: https://github.com/gugod/App-perlbrew/wiki/Perlbrew-In-Shell-Scripts :

#!/bin/bash
## These 3 lines are mandatory.
export PERLBREW_ROOT=/opt/perlbrew
export PERLBREW_HOME=/tmp/.perlbrew
source ${PERLBREW_ROOT}/etc/bashrc

## Do stuff with 5.14.1
perlbrew use 5.14.1
perl /app/my-modern-program

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM