我有一个shell脚本除了设置一堆环境变量之外什么都不做:
export MYROOTDIR=/home/myuser/mytools
export PATH=$MYROOTDIR/bin:$PATH
export MYVERSION=0.4a
我有一个perl脚本,我希望perl脚本以某种方式让perl脚本与shell脚本中列出的env变量一起运行。我需要在perl脚本中发生这种情况,但我不希望perlscript的调用者必须首先手动获取shellcript。
尝试运行时
system("sh myshell.sh")
env vars不会“传播”到运行perl脚本的进程。
有办法做到这一点吗?
答案 0 :(得分:4)
要正确回答这个问题,我需要了解更多。
export VAR=value
形式(即具有固定赋值,无变量替换或命令替换)?根据这些问题的答案,存在不同复杂程度的选项。
感谢您的澄清。好的,这是怎么做的。除了分配变量之外,您的脚本没有副作用。这允许从perl中运行脚本。我们如何知道脚本中导出的变量?我们可以尝试解析shell脚本,但这不是Unix使用工具做得好的事情并将它们链接在一起的方式。相反,我们使用shell的export -p
命令让它宣布所有导出的变量及其值。为了找到仅脚本实际设置的变量,而不是所有其他噪声,脚本是使用env -i
(另一个低估的POSIX gem)的干净环境启动的。
全部放在一起:
#!/usr/bin/env perl
use strict;
use warnings;
my @cmd = (
"env", "-i", "PATH=$ENV{PATH}", "sh", "-c", ". ./myshell.sh; export -p"
);
open (my $SCRIPT, '-|', @cmd) or die;
while (<$SCRIPT>) {
next unless /^export ([^=]*)=(.*)/;
print "\$ENV{$1} = '$2'\n";
$ENV{$1} = $2;
}
close $SCRIPT;
注意:
env -i
所需的所有环境转移到myshell.sh
,例如PATH
。PWD
变量;如果你不想在你的perl ENV哈希中使用它,请在第一个next if $1 eq 'PWD';
之后添加next
。这应该可以解决问题。如果有效,请告诉我。
另见:
答案 1 :(得分:1)
答案 2 :(得分:0)
您可以在BEGIN块中设置环境变量。 BEGIN块在其余代码之前执行,在此块中设置环境变量使其在编译和运行之前对其余代码可见。 如果你有任何perl模块根据环境设置“使用”,BEGIN块就可以实现。
Perl使用特殊的散列%ENV来维护环境变量。 您可以修改此哈希的内容以设置env变量。
示例:
BEGIN
{
$ENV { 'MYROOTDIR' } = '/home/myuser/mytools';
$ENV { 'PATH' } = "$ENV{ 'MYROOTDIR' }/bin:$ENV{ 'PATH' }";
}
答案 3 :(得分:0)
shell脚本设置变量,然后调用perl程序会不会更容易?
即:
run.sh:
#!/bin/sh
export MYROOTDIR=/home/myuser/mytools
export PATH=$MYROOTDIR/bin:$PATH
export MYVERSION=0.4a
./program.pl
答案 4 :(得分:0)
现在可以使用Env::Modify
完成此操作,只需对现有代码进行少量更改。
use Env::Modify 'system';
...
system("sh myshell.sh");
print $ENV{MYROOTDIR}; # "/home/myuser/mytools"
或者如果您的所有shell脚本都修改了环境,您可以使用source
函数
use Env::Modify `source`;
source("myshell.sh");
print $ENV{MYVERSION}; # "0.4a"