Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Distro Pkg-Managed, broken, sudo clears $PERL5LIB

by Intrepid (Deacon)
on Sep 27, 2010 at 18:02 UTC ( #862257=perlmeditation: print w/replies, xml ) Need Help??

Seeing error mentioned with (ExtUtils::MakeMaker) ExtUtils::Install (.pm)

I noticed that this recent Perlmonks node says in part:

I use Ubuntu and typing # cpan WWW::Mechanize
produced the following […]

In a follow-up a Monk stated:

If you're using the (Ubuntu) stock Perl interpreter, you want to install Perl modules through apt-get (or whatever other package tool is en vogue on Ubuntu currently). The package is libwww-mechanize-perl.

Don't install modules into the system Perl. Always use the system package manager. If you want to use cpan to install (more current) versions from CPAN, compile and install your own Perl or use local::lib. Neither is hard.

My purpose in repeating the advice from node follow-up is to emphasize that I agree this is correct. I run Perl on Ubuntu as well. I agree that one uses APT to package­manage the system software. I also would add that I use $PERL5LIB in conjunction with a local software tree rooted at /opt which I populate with newer or unprovided CPAN modules built and installed by using manual build-install procedures.

I did as described with the recent release of ExtUtils::MakeMaker and the environmental variable $PERL5LIB puts the location of the newer version (that version newer than the one supplied as part of the distro package installable via APT) in precedence over the older one. Yet, I was bit at make install time with make reporting the following error about line 557 in ExtUtils/

Not a HASH reference at [some path in standard system]/ExtUtils/ line 557.
I think I know how come that happens.

A googlication returned results which indicate that outside the Perlmonks discussions there have been repeatable encounters with this same error.

When trying to install some recent CPAN packages I encountered this failure as well. However, for me this bit in a confusing manner. Some modules from CPAN require the build and installation of many, many prerequisite dependencies from other CPAN packages, and the Text-Pipe and Text-Pipe-HTML packages (Text-Pipe-HTML-1.100880 at this writing) was one of those. Those dependencies installed under cpanplus without a hitch. Why the final objective failed when all the dependencies install is unclear to me at this point. But it is probably not relevent.

Could there be a bug in an older version of EUMM::Install? Why not? Software often has bugs. However, I do not think that is what is biting here. Instead, I think it is a backwards-incompatible change in how a ExtUtils:: routine is being called.

It seems to me that if I generate my Makefile using a different release of EU::MM then I still cannot avoid this show-stopping error on make install. See here for the distinction created by changing the EU::MM found (without deleting any package-managed files from the hard disk, btw):

PERL5LIB="/opt/cpan-installed/perl/lib/perl5:/opt/cpan-installed/perl/ +module-lib/5.10/arch/i486-linux-gnu-thread-multi:/opt/cpan-installed/ +perl/module-lib/5.10/lib" perl -MExtUtils::Install -e 'printf "%-62s + %s\n", $INC{q|ExtUtils/|}, ExtUtils::Install->VERSION' /opt/cpan-installed/perl/lib/perl5/ExtUtils/ 1.52
PERL5LIB="" perl -MExtUtils::Install -e 'printf "%-62s %s\n", $INC{q| +ExtUtils/|},ExtUtils::Install->VERSION' /usr/share/perl/5.10/ExtUtils/ 1.44

Can I remind readers of something that seems often forgotten? When the first glance is taken at an install problem that arises from ExtUtils::, the complexity of the actual succession of events during the process is often blurred in one's mind. ExtUtils::MakeMaker is invoked on a file Makefile.PL and a file Makefile is generated as a result. This file has targets and declarative definitions used in stating target recipes (how to "do" the target). The ExtUtils::MakeMaker library provides code that generates make declarations and target recipes. But the ExtUtils:: namespace also provides libraries that supply some callable code (subroutines) which are used by the make target recipes while make causes execution of processes when the user types make install.

That's two really different kinds of things that are contained in the ExtUtils:: namespace that are distinguished from each other not only by level of indirection but by when they are happening. The environment may change between when make code is generated and when the make executable is invoked on a Makefile …you could run make pure_site_install years after the Makefile was generated by MakeMaker.

With the default system installation¹ provided by my GNU/Linux vendor (Ubuntu) present, I cannot avoid having the "apparently defective" code called even when $PERL5LIB is telling make, and thus telling perl (from $PERL5LIB's status as a "mere environmental variable"), that it ought to be looking elsewhere for the newer ExtUtils::Install. That initially confounded me. But I was confounded because I'd started with a naïve idea of what was wrong (that there was just a bug in the older ExtUtils::Install routine being flagged by the exception handling).

The problem really arises from: The make install step is running under sudo!And by default, sudo clears the user's env completely. Thus we can only get the newer ExtUtils::Install at install time (when it is run, under commands spawned by make), by saying:

sudo PERL5LIB="/opt/cpan-installed/perl/lib/perl5:/opt/cpan-installed +/perl/module-lib/5.10/arch/i486-linux-gnu-thread-multi:/opt/cpan-inst +alled/perl/module-lib/5.10/lib" \ make pure_site_install
Once we have installed (to an alternate $PERL5LIB directory path) a current ExtUtils::Install:

I think that you can use o conf init or a manual edit of ~/.cpan/CPAN/
    'make_install_make_command' => q[sudo PERL5LIB="${PERL5LIB}" make] (I use cpanplus, not, but yitzchak pointed out this config param and I verified that it appears to work well).

Since cpanplus might be used instead (and is, by me), the following fix might be tested for that setup:     $conf->set_program( sudo => '/usr/bin/sudo PERL5LIB="${PERL5LIB}" ' ); Notice that there is a space before the closing quote; by default the cpanplus config item "sudo" was terminated with that space, and I preserved it in case it is meaningful to the operation of cpanplus, or more specifically, to the generated Make file target-making directives that are going to be used at install-time.

To get to the config setting above (understanding that we are already using cpanplus and this is a change to existing settings), I did:

  1. $ cpanp
  2. CPAN Terminal> s reconfigure
I choose 8 from the selection menu that appears:

Welcome to the CPANPLUS configuration. Please select which
parts you wish to configure

Defaults are taken from your current configuration.
If you would save now, your settings would be written to:
  1> Select Configuration file
  2> Setup CLI Programs
  3> Setup CPANPLUS Home directory
  4> Setup FTP/Email settings
  5> Setup basic preferences
  6> Setup installer settings
  7> Select mirrors
  8> Edit configuration file
  9> Save & exit
 10> Quit without saving

Save & exit (choice 9) and then try installing the failing CPAN package again, YMMV, caveat perl-user.

    ¹ : installation of Perl and the core modules, that is.

By the way, now that I've shown my solution to get a make install to work, let me add for those with a different focus, that I don't hold the analytical opinion that I or someone else on PMo has yet shown that there is a bug in the older ExtUtils::Install module (version 1.44 on my local system). What can be deduced more plausibly is only that using a newer revision of other ExtUtils:: library code as part of CPAN package installing, is creating calls in Makefile "code" (target-building recipes) that may be syntactically broken for the older subroutine. In other words, backward-compatibility was broken.

Replies are listed 'Best First'.
Re: Distro Pkg-Managed, broken, sudo clears $PERL5LIB (sudoers)
by shmem (Chancellor) on Sep 28, 2010 at 15:51 UTC

    Not a big deal.

    sudo(8) clears the environment depending on the content of the sudoers file. Consulting the sudoers(5) manual page helps.

    Defaults env_keep += "PERL5LIB PERL5OPTS" # or even Defaults:Intrepid env_keep += "PERL5LIB PERL5OPTS"

    in the sudoers file fixes that.

      Sudo clears the environment for a reason.

      The fact that PERL5LIB can replace modules run with borrowed privileges makes it particularly important to get blocked, or control over what code will be executed is lost.

      Rather than honoring whatever library settings the sudoer provides, that choice should be made on the side of the target account (root, say).

      In the OP situation sudo can give the person updating site add-ons full control, which can be used then to set paths explicitly, or set up the environment with fixed settings in harmony with the local installation preferences.

      But please do not make passing on PERL5LIB a default.

      Btw, if perl detects being run with borrowed privileges it ignores PERL5LIB on its own account, and turns on other safety precautions, too (see perlsec). But this will not happen under sudo, as sudo sets real and effective IDs at the same time and thus hides the fact that a transfer of privileges has taken place at all.

      In order to keep site add-ons visible even if running in taint mode, PERL5LIB may be not the best mechanism to depend on. Many distributions reserve file hierarchies for site and/or vendor libraries for that reason. Debian, e.g., compiles perl with /usr/local subdirectories in @INC, where distro packages never go. You could still use /opt/foobar with a symbolic link in the distro's idea of the site-specific location pointing there.

        But please do not make passing on PERL5LIB a default.

        Why? The PERL5LIB environment variable is set up after the fact (of changing $< and $>) of getting broader permissions via sudo.

        So, a well thought-out privilege evelating scheme is more important than the passing of an environment variable while changing $UID, becaue you could set that very ENV var by hand, after running sudo.

        That statement of yours which I quoted looks to me very much like the bogus "eval is evil" and "don't use system $string" warnings, which are nonsense as absolutes, i.e. without context.

Re: Distro Pkg-Managed, broken, sudo clears $PERL5LIB
by sundialsvc4 (Abbot) on Oct 13, 2010 at 17:32 UTC

    Many OS distro-management packages are written in Perl, and those are set up to expect a very particular CPAN setup... which they manage, like everything else, using their own package management system.   (Yeah, the cat is eating its own tail, etc, but it actually works.)

    However, truly-dreadful things can happen if you inadvertantly break it.   What is slick-as-a-whistle can turn into something that has fallen and can’t get up.   And some distro-management software seems to be running on a wing and a prayer in the best of times.

    The admonition therefore is a very sound one:   for code that (say) you are preparing for deployment to a web-site somewhere, set up your own CPAN-library directory, your own .cpan configuration file, everything.   Add it to your local setting of PERL5LIB.   Write scripts to add, and to undo, those environment changes.   The techniques are exactly those that you’d use to run as a non-root user at a public web-hosting service.   You can’t altogether eliminate their package repositories from @INC, because they normally compile those pathnames straight into their Perl executables if they themselves rely upon it, but this is usually not an issue.   (And since @INC is, after all, just an ordinary list, you can replace it in its entirety, within a particular piece of code.)

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://862257]
Approved by Erez
Front-paged by Erez
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (1)
As of 2022-11-26 19:37 GMT
Find Nodes?
    Voting Booth?