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的值?
答案 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
)才能被一口气看到。
可以用env
或printenv
列出环境变量,而set
列出所有变量,包括本地变量和环境变量。
上面是指bash
shell。 “环境”的概念在其他外壳程序中是相同的,并且在其中也适用相同的推理。为了使变量在子进程中可见,我们需要将其设置为全局(“环境变量”)。区别在于如何执行此操作。
在csh
/ tcsh
中使用
setenv env "value"
代替set var = "value"
的是什么将创建局部变量。
除了使用全局(“环境”)变量而不是局部变量之外,还可以将变量传递给Perl代码。有关使用单线执行此操作的示例,请参见this post和this 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
是私有变量(按惯例小写)。
sh
和bash
这些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}...'
csh
和tcsh
这些shell使用不同的语法来设置私有变量和环境变量。
要设置私有变量,请使用set
。
set var val
要设置环境变量,请使用setenv
。
setenv VAR val
perl -e'...$ENV{VAR}...'
以上方法更改了外壳及其创建的所有后续子代的环境。