在 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 文件一样是大小写无关的。
Titi
和 TITI
都是同一个变量的名称,在 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
我正在尝试在 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 文件一样是大小写无关的。
Titi
和 TITI
都是同一个变量的名称,在 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