Perl的ENV哈希中没有的怪异环境变量

时间:2019-04-18 19:28:07

标签: perl environment-variables

Perl可以访问一些环境变量:

> echo $HOST
xtt006
> perl -E 'say $ENV{HOST}'
xtt006
> perl -E 'say `echo \$HOST`'
xtt006

但是很显然,ENV哈希表中还没有另一类环境变量:

> echo $env
opsd
> perl -E 'say $ENV{env}'
(no response from Perl)
> perl -E 'say `echo \$env`'
(no response from Perl)

这是怎么回事? Perl是否可以通过另一种技术获得$ env的值?

3 个答案:

答案 0 :(得分:3)

尝试export从shell中输入变量。这会将其从Shell的变量列表移至所有子进程将能够看到的环境。

export env
perl -E 'say $ENV{env}'

这应该让它显示出来。

答案 1 :(得分:3)

来自%ENV in perlvar  (我的重点)

  

哈希%ENV包含您当前的环境

环境是从启动Perl进程的过程(这里是外壳程序)继承的。

但是,shell variables可以是 local ,它们不会传递给形成环境并由子进程继承的子进程或全局进程。全局文件大多是在启动时从配置文件中读取的,但是如果以后要添加它们,则需要exported

  

像上面示例中那样创建的变量仅适用于当前shell。它是一个局部变量:当前shell的子进程将不知道此变量。为了将变量传递到子Shell,我们需要使用export内置命令将其导出。导出的变量称为环境变量。设置和导出通常是一步完成的:

export VARNAME="value" 

(我的重点)根据您的描述,似乎$env是作为局部变量(带有set)添加的,然后还需要导出(export env)才能被一口气看到。

可以用envprintenv列出环境变量,而set列出所有变量,包括本地变量和环境变量。


上面是指bash shell。 “环境”的概念在其他外壳程序中是相同的,并且在其中也适用相同的推理。为了使变量在子进程中可见,我们需要将其设置为全局(“环境变量”)。区别在于如何执行此操作。

csh / tcsh中使用

setenv env "value"

代替set var = "value"的是什么将创建局部变量。


除了使用全局(“环境”)变量而不是局部变量之外,还可以将变量传递给Perl代码。有关使用单线执行此操作的示例,请参见this postthis post。如果调用了实际的脚本,则使其带有参数。标准且最好的方法是使用Getopt::Long

这不是对用户的特殊要求;他们使用您的脚本并需要适当地调用它。

答案 2 :(得分:2)

就像Perl具有私有变量(my $x)和环境变量($ENV{Y})一样,shell也是如此。

$ perl <<'.'
my $x = "x";
$ENV{Y}="Y";
system 'echo "<$x> <$Y>"';
.
<> <Y>

$ sh <<'.'
x=x
export Y=Y
perl -le'print "<$x> <$ENV{Y}>";'
.
<> <Y>

$ csh <<'.'
set x x
setenv Y Y
perl -le'print "<$x> <$ENV{Y}>";'
.
<> <Y>

支持私有变量是一件好事,而不是一件奇怪的事。

在您的示例中,$HOST是环境变量(按惯例大写),而$env是私有变量(按惯例小写)。


shbash

这些shell使用相同的机制分配给私有变量和环境变量。

要创建环境变量,请使用export将私有变量提升为环境。

VAR=val
export VAR
perl -e'...$ENV{VAR}...'

export VAR
VAR=val
perl -e'...$ENV{VAR}...'

促销和任务可以组合。

export VAR=val
perl -e'...$ENV{VAR}...'

以上方法更改了外壳及其创建的所有后续子代的环境。以下方法可用于更改特定孩子的环境:

VAR=val perl -e'...$ENV{VAR}...'

该方法也可以用于有效地推广私有变量:

var=val
VAR="$var" perl -e'...$ENV{VAR}...'

cshtcsh

这些shell使用不同的语法来设置私有变量和环境变量。

要设置私有变量,请使用set

set var val

要设置环境变量,请使用setenv

setenv VAR val
perl -e'...$ENV{VAR}...'

以上方法更改了外壳及其创建的所有后续子代的环境。