将环境变量设置为从 perl 脚本执行的 shell
Posted
技术标签:
【中文标题】将环境变量设置为从 perl 脚本执行的 shell【英文标题】:Setting environment variable to shell executed from perl script 【发布时间】:2021-06-17 04:21:01 【问题描述】:我正在运行一个 perl 文件 a.pm,它通过系统命令调用 b.sh。
这里,b.sh 使用的是find
实用程序,其路径是/usr/local/bin。
如果我直接在机器上的 shell 上运行env
,我会得到如下PATH
变量的输出。
PATH=/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/home/bin:/home/bin/samba::/home/venv/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin`
这就是为什么如果我直接从 shell 运行 b.sh,它能够执行 find 实用程序。
现在,如果我使用 system()
通过 a.pm 运行 b.sh,并且当我在 中打印 PATH
环境变量时b.sh,它来了
/bin:/usr/bin:/usr/X11R6/bin:/home/bin:/home/perl5/bin
其中没有/usr/local/bin
,这就是find
命令失败的原因。
如果我在调用 system(b.sh)
之前尝试在 perl 中打印所有 ENV 变量,则不会打印 PATH 变量。
现在,我尝试在调用 system(b.sh) 之前在 a.pm 文件中添加路径变量,如下所示。
$ENV'PATH' = '/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin:/home/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/';
现在,如果我在调用 system(b.sh)
之前尝试打印 perl
中的所有 ENV
变量,则 PATH 变量将打印上述值。
仍然执行a.pm文件,b.sh中打印的PATH变量是一样的:
/bin:/usr/bin:/usr/X11R6/bin:/home/bin:/home/perl5/bin
如何将对应路径/usr/local/bin添加到使用a.pm调用的b.sh的shell中? p>
【问题讨论】:
你如何调用你的shell脚本? b.sh 有 shebang 吗?这是什么? 我在 a.pm 文件中使用 system(b.sh)。我也可以直接从 linux shell 运行 b.sh,然后它就可以正常工作了。 没有程序可以改变其父进程的环境变量。这是环境变量在 UNIX 上的一般工作方式的一部分——它们是从父级复制到子级,而不是从子级复制到父级。 ...请注意,更改$ENV'PATH'
确实 更改 PATH
以用于从同一个 Perl 解释器启动的未来子进程。 minimal reproducible example 我们可以在不进行更改的情况下运行以查看它是否不起作用,这将是一个合适的起点。
请注意,如果您有一个 ENV
或 BASH_ENV
指向覆盖 PATH
的文件的名称,这是由 system()
启动的 shell 具有父进程设置的 PATH 被覆盖。
【参考方案1】:
我怀疑 Perl 程序要么正在修改它从调用它的 shell 获得的路径,要么你在某处遗漏了一步。例如,如果您从不同的环境调用 Perl 程序,它可能会有不同的PATH
。
不过,您似乎已经找到了答案。将必要的目录添加到 Perl 程序的 PATH 中。但是,你说这行不通。再说一次,我认为你没有包括一些步骤。我怀疑您运行系统的方式会覆盖从父级继承的 PATH。
例如,这是一个仅运行 shell 脚本的小型 Perl 程序:
#!perl
use v5.10;
$ENVPATH = '/bin:/usr/bin';
say "PATH in Perl is $ENVPATH";
system( "sh ./pather.sh" );
shell 脚本回显 PATH:
#!/bin/sh
echo "PATH in shell:" $PATH
当我运行它时,两个 PATH 都匹配:
PATH in Perl is /bin:/usr/bin
PATH in shell: /bin:/usr/bin
但是,system
中的命令可能是别的东西。 -l
开关将 shell 视为登录 shell,因此它将加载各种配置文件等:
system( "sh -l ./pather.sh" );
现在,shell 脚本中的 PATH 有所不同,因为我的特定配置文件覆盖了 PATH:
PATH in Perl is /bin:/usr/bin
Path in shell: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/usr/local/go/bin:...
我们的答案可以更有针对性,您可以制作一个最小的工作示例,我们可以在其中看到演示问题的实际代码。由于我们看不到您在 system
中实际运行的内容,因此我们只能猜测。
【讨论】:
以上是关于将环境变量设置为从 perl 脚本执行的 shell的主要内容,如果未能解决你的问题,请参考以下文章