在 Perl 中设置区分大小写的 Windows 环境变量

Set case sensitive Windows environment variables in Perl

我正在尝试在 Perl 中设置一些区分大小写的 Windows 环境变量,以便在 shell 脚本中使用它们。

但是,当我尝试在使用 system 命令和 运行 从 Perl 调用的 shell 脚本中以小写形式使用它们时,我注意到环境变量都是大写的Msys.

例如下面的脚本:

#!perl

system "echo echo TOTO=$TOTO > toto.sh";
system "echo echo Titi=$Titi >> toto.sh";
system "echo echo TITI=$TITI >> toto.sh";
$ENV{'TOTO'}="0+0";
$ENV{'Titi'}="Not toto!";
system("sh toto.sh");

returns(而在 Msys 中为 运行)以下输出:

TOTO=0+0
Titi=
TITI=Not toto!

有人知道这在 Windows 中是否可行(即如何设置环境变量 Titi 而不是 TITI)?

谢谢

以下应独立于套管问题应用。

让我们看第一行:

system "echo echo TOTO=$TOTO > toto.sh";

如果你打电话给

echo echo TOTO=$TOTO

在您的命令行上,输出将是:

echo TOTO=$TOTO

这好像是,你想要什么。

然而,你用系统调用的行首先由 perl 解释,所以你转义的 \$ 变成了 $。

然后输出取决于 $TOTO 的当前值(在您在脚本中设置环境变量之前),它可能是空的。

您应该将所有这些系统调用更改为单引号:

 system 'echo echo TOTO=$TOTO > toto.sh';

如果你这样做,你将得到以下输出:

TOTO=0+0
Titi=
TITI=not TOTO

Titi 是空的,因为你没有给它赋值。

Windows 环境变量标识符与 Windows 文件一样是大小写无关的。

TitiTITI 都是同一个变量的名称,在 Perl 中可以通过 $ENV{TITI}$ENV{Titi} 访问其值。同样,命令行上的 echo %TITI%echo %Titi% 将给出相同的结果。

如果您解释为什么需要区分大小写的环境变量名称,那么我们可能会帮助您。

似乎无法做到:Windows 将只使用大写变量。

我的做法是通过将变量替换为对应的大写字母来临时转换脚本,并在使用它们后将它们切换回之前的状态。

在我的例子中,我不得不处理从 shell 脚本 Run_Session.sh 导出的变量。我创建了一个 Perl 脚本来执行大写替换,这就是结果。

###############################
## SUBROUTINE uc_variables   ##
#-----------------------------#
# This subroutine convert the environment variables exported 
# by the top level script to upper case, and can revert the operation.
#
# Input:
# -----
# $mode: "ON" (default) or "OFF"
#
# Output:
# ------
# N/A
#-----------------------#
#########################
sub uc_variables {
    my $mode=shift;
    chdir $Bin;
    if ($mode eq "OFF") {
        foreach my $bak (glob "{*,*/*}.sh.bak") {
            (my $orig = $bak)=~s/\.bak//;
            move($bak,$orig);
        }
    } else {
        #Check if back-up already exists
        uc_variables("OFF") if (-e "Run_Session.sh.bak");
        #List variables to update
        my %uc_var;
        open RUN_SESSION,"<Run_Session.sh" or die "Error while reading Run_Session.sh ($!)\n";
        map { /export\s+(\w*[a-z]\w*)/ and ($uc_var{}=uc())=~s/Directory/DIR/i } <RUN_SESSION>;
        close RUN_SESSION;
        #Replace variables
        foreach my $shell (glob "{*,*/*}.sh") {
            #Back-up
            copy($shell,"$shell.bak");
            #Read data
            open SHELL,"<$shell" or die "Error while reading $shell ($!)\n";
            my $SHELL = join("", <SHELL>);
            close SHELL;
            #Replace
            map { $SHELL=~s/$_/$uc_var{$_}/g } keys %uc_var;
            #Print
            open SHELL,">$shell" or die "Error while writing in $shell ($!)\n";
            print SHELL $SHELL;
            close SHELL;
        }
    }
} #end of uc_variables