3

Is that anyway in Perl to expand the variable by in $ENV{$variable}?

I exported "a=T" and "T=b" in shell, and I run the Perl script in which print "$ENV{$a}\n", but nothing printed. I want to "b" can be printed, then how should I do in Perl?

michael_J
  • 133
  • 1
  • 3

1 Answers1

11

Those environment variables should be chained you say, so

$ENV{ $ENV{a} };

Note: not $a but a, like $ENV{USER} etc. This uses the hash %ENV (see perlvar), which has the current environment, so with keys being names of environment variables.


It is apparently of interest to use a Perl variable (for the shell variable's name) in %ENV, and not a string literal as above. In that case we need to pass that shell variable, its name or the value, to the Perl program somehow so to have it stored in a variable; can't just use it directly.

Incidentally, one of the ways to pass a variable from shell to Perl is precisely by exporting it, what then makes it available via %ENV. However, it can also be passed as usual, via command line. Assuming the use of a Perl one-liner (common in shell scripts), we have two options for how to pass

  • As an argument, perl -we'...' "$var", in which case it is available in @ARGV

  • Via the -s command switch, perl -s -we'...' -- -shv="$var", what sets up $shv variable in the one-liner, with the value $var. The -- mark the start of arguments.

See this post for details, and perhaps this one for another, more involved, example.

Note  A comment asks how to pass variable's name (string a), not its value ($a). This doesn't seem as the best design to me; if the name of a variable for some reason need be passed around then it makes sense to store that in a variable (var="a") and pass that variable, as above.

But if the idea is indeed to pass the name itself around, then do that instead, so either of

perl -we'...' "a"
perl -we'...' -s -- -shv="a"

The rest is the same and %ENV uses the variable that got assigned the input.

If a full Perl script is used (not a one-liner) then use Getopt::Long to nicely handle arugments.


 A comment asks about passing the shell variable's name to a Perl variable — so a from the OP, not its value $a. I am a little uncertain of the utility of that but it is of course possible.

The two ways for how to pass a variable from shell to Perl then differ in what is passed.

zdim
  • 64,580
  • 5
  • 52
  • 81
  • thank you. Another question is if "a=T" is exported on the current shell, and in my Perl script : $test=a; print "$ENV{$ENV{test}}"; and then i run this script but it prints nothing. Can you help it again? – michael_J Nov 05 '19 at 07:26
  • @michael_J Ah ... no, can't do that -- that shell's _environment_ variable `a` is provided in the `%ENV` hash, as a key. But to use it as a "normal" variable in the Perl script you have to somehow pass it to the script; can't use either `a` or `$a`. One way to pass variables from the shell to a Perl script is in fact precisely by using the environment (you export the variable in the shell and then Perl script can use it via `%ENV`). Or, you can pass it as an argument for the script (in two ways) – zdim Nov 05 '19 at 07:37
  • @michael_J For how to pass Bash variables to a Perl one-liner, see for example [this post](https://stackoverflow.com/a/51713578/4653379) and [this post](https://stackoverflow.com/a/56200990/4653379) (perhaps [this](https://stackoverflow.com/a/54059744/4653379) can also be useful). If you call a full Perl script (not one-liner) then I'd do away with all that and just nicely use command-line arguents via [Getopt::Long](https://perldoc.perl.org/Getopt/Long.html) – zdim Nov 05 '19 at 08:13
  • @michael_J Added comments on this to my answer. – zdim Nov 05 '19 at 08:31
  • @michael_J Updated/edited the addition with with discussion on passing the _name_ of the variable – zdim Nov 05 '19 at 09:08