Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have a hash, created from a text file, with an element along the lines of %myhash{$mykey}="$FRED/thingy.txt". When I issue an open command for "<%myhash{$mykey}", it fails to resolve the environment variable part and reports that it cannot find the file "$FRED/thingy.txt". I've got "use Env;" and other environment variables are being resolved correctly (including some referencing $FRED). How do I tell Perl that the contents of %myhash{$mykey} contains an environment variable and that it should resolve it? Apologies if this is straightforward, but I can't find it in my Perl manual, or through a search. Cheers, J.
  • Comment on Forced resolution of environment variables

Replies are listed 'Best First'.
Re: Forced resolution of environment variables
by insaniac (Friar) on Oct 22, 2004 at 15:04 UTC
    hey
    i think you mean $myhash{$mykey}, right?
    second: when i want to use environmental variables (shell variables to keep it short ;) ), i use $ENV{VARNAME}, for instance $ENV{HOME}. and then you don't have to use the use Env; thingie
    hope this helps..
    --
    to ask a question is a moment of shame
    to remain ignorant is a lifelong shame

      I don't think I've ever used use Env. I've never really liked things that pollute the namespace to any real extent. Keeping things within the normal %ENV hash and pulling it when needed is a lot cleaner to my mind.

      --- Jay

      All code is untested unless otherwise stated.

Re: Forced resolution of environment variables
by Fletch (Bishop) on Oct 22, 2004 at 15:10 UTC

    That's because you never pass the string through perl so there's no way it could interpolate it. You'd want to use eval or s///e, but if you don't trust your input you'd want to be careful doing that. You might also check out a module like AppConfig which gives you a config file parser which will do this sort of interpolation to some degree.

Re: Forced resolution of environment variables
by tye (Sage) on Oct 22, 2004 at 16:11 UTC

    "$FRED" only gets expanded if it is in Perl code. It sounds like you have that in data. So post-process your data with:

    s/\$([A-Z0-9_]+)/$ENV{$1}/g for $myhash{$mykey}, ...;

    (which doesn't require "use Env;" which is something that I would never use -- it sounds rather dangerous in some situations, allowing people to throw in variables not in your control and just to save you from typing 'ENV{' and '}'.)

    - tye        

      That's only "dangerous" in a place were someone else controls your environment. But if someone else controls your environment, even a use strict is "dangerous", as that will allow the attacker to execute arbitrary code on your behalf. (Because the attacker can then set PERL5LIB, PERL5OPT, PERLIO, PERL5SHELL, and some other variables to make life annoying).
        Not in taint mode, which should always be used in any code executing on someone else's behalf.
      Thanks, folks. Interesting points about "use Env;" too.