我正在尝试从perl脚本调用bat文件,如下所示:
system("call D:/SIP/run_$file_idx.bat");
但是我发现bat中的环境变量无法解决。 如果我从命令提示符单独运行bat文件,它就可以运行。
system()是否创建了一个新环境并执行bat文件? 我错过了什么?
if (($ENV{'IPSL_RUN_FLAG'}) eq "TRUE") {
my $Book = $Excel->Workbooks->Open(
"$ENV{'IPSL_TESTCASES_PATH'}IPSLFeatureLoadRunResults.xls");
# Make transparent where the IPSL tarball is installed.
# Have ControlPanel save results here.
# You can dynamically obtain the number of worksheets, rows, and columns
# through the Excel OLE interface. Excel's Visual Basic Editor has more
# information on the Excel OLE interface. Here we just use the first
# worksheet, rows 1 through 4 and columns 1 through 3.
# select worksheet number 1 (you can also select a worksheet by name)
my $count=0;
my $Sheet = $Book->Worksheets("LOADDATA");
my $tmp=0;
foreach my $row (13..776) {
foreach my $col (17..17) {
if(($Sheet->Cells($row,$col)->{'Value'} eq "Failed") ||
($Sheet->Cells($row,$col)->{'Value'} eq "No Run") ) {
$cnt_of_current_rerun_testcases++;
foreach my $col (18..18) {
# skip empty cells
next unless defined $Sheet->Cells($row,$col)->{'Value'};
my $a = $Sheet->Cells($row,$col)->{'Value'};
my $i = index($a, 'run');
$a = substr($a, 0, $i); #remove runTest*
print OUT "\n";
if($count == 0) {
print OUT "\nREM ";
print OUT "*" x 100;
print OUT "\n";
print OUT "\ntaskkill /F /FI \"USERNAME eq %USERNAME%\" /IM ips32.exe";
print OUT "\ntaskkill /F /FI \"USERNAME eq %USERNAME%\" /IM ipsldb.exe";
print OUT "\ntaskkill /F /FI \"USERNAME eq %USERNAME%\" /IM ipsltiu.ex\n";
}
print OUT "c:\n";
print OUT "\ncd ";
$a =~ s/%I/\"%I/g;
$a=~s/H%/H%\"/g;
print OUT " $a\n";
print OUT "\n";
print OUT "CALL run_SubscribeFeatureOnHIQ.bat";
print OUT "\n";
print OUT "sleep 10\n";
print OUT "\ncd ";
print OUT " $a\n";
print OUT "\n";
print OUT "CALL ";
$i=$Sheet->Cells($row,$col)->{'Value'};
$i=~ s/%I/\"%I/g;
$i=~s/H%/H%\"/g;
print OUT $i;
#print OUT $Sheet->Cells($row,$col)->{'Value'};
print OUT "\n";
$count++;
if($count == $no_simul_tcases) {
$sleep_cnt++;
print OUT "echo Going for sleep $sleep_cnt\n";
print OUT "SLEEP 300";
print OUT "\n";
$count=0;
}
}
}
}
}
print OUT "\ntaskkill /F /FI \"USERNAME eq %USERNAME%\" /IM ips32.exe";
print OUT "\ntaskkill /F /FI \"USERNAME eq %USERNAME%\" /IM ipsldb.exe";
print OUT "\ntaskkill /F /FI \"USERNAME eq %USERNAME%\" /IM ipsltiu.ex\n";
print OUT "\nset IPSL_RUN_FLAG=TRUE";
close OUT ;
system(\"start $ENV{'IPSL_TESTCASES_PATH'}SIP\\run_$file_idx.bat\");
批处理文件是:
taskkill /F /FI "USERNAME eq %USERNAME%" /IM ips32.exe
taskkill /F /FI "USERNAME eq %USERNAME%" /IM ipsldb.exe
taskkill /F /FI "USERNAME eq %USERNAME%" /IM ipsltiu.ex
c:
cd "%IPSL_TESTCASES_PATH%"SIP\TestCASE\FEATURESINT\INT_cfSRS\INT_cfSRS_cfSERRNG\
CALL run_SubscribeFeatureOnHIQ.bat
sleep 10
cd "%IPSL_TESTCASES_PATH%"SIP\TestCASE\FEATURESINT\INT_cfSRS\INT_cfSRS_cfSERRNG\
CALL "%IPSL_TESTCASES_PATH%"SIP\TestCASE\FEATURESINT\INT_cfSRS\INT_cfSRS_cfSERRNG\runTest_SRS_INT_SERRNG.bat
可能的解决方法:
通过使用exec并专门将ENV写入bat文件给了我一个解决方法:
print OUT map { "set $_=$ENV{$_}\n" }
qw( path USERPROFILE USERNAME ProgramFiles ComSpec APPDATA );
但是系统()仍然会出现问题。我在回答者中尝试了思南的建议..
答案 0 :(得分:1)
子进程继承其父进程的环境。 bat文件应该与Perl脚本具有相同的环境。如果您没有正确设置环境,您的bat文件将无法看到它。
你可以扩展你的答案来展示你的测试案例,类似于思南所做的事情吗?虽然您在评论中说代码很简单,但事实并非如此。向我们展示您拥有的完整Perl程序以及您拥有的完整bat文件。不要让我们猜测或做很多工作来弄清楚你在做什么。
更新:现在您已经提供了一些代码,开始从中切割部分以制作仍然显示问题的最简单的测试用例。在调查这些问题时,请停止处理大脚本并编写一个脚本来解决您认为自己遇到的问题。这样,你可以将它与其他可能搞乱的东西隔离开来。
答案 1 :(得分:0)
更新2:让我们更仔细地查看您的system
来电:
system(\"start $ENV{'IPSL_TESTCASES_PATH'}SIP\\run_$file_idx.bat\");
这应该是语法错误,您的脚本甚至不能调用批处理文件。尝试
system(qq{start $ENV{IPSL_TESTCASES_PATH}SIP\\run_$file_idx.bat\\});
更新1:查看您发布的代码,您在系统调用中使用start
。这会启动一个新的cmd.exe
进程,并且在您的脚本终止后cmd.exe
将保持很长时间。但是,我仍然没有按照您的描述观察行为,我将更仔细地查看您的代码转储。
C:\Temp> cat bg.bat @echo %YAEV% @echo %*
C:\Temp> cat t.pl
#!/usr/local/bin/perl
use strict;
use warnings;
$ENV{YAEV} = 'Yet another environment variable';
system 'start bg.bat "This is a test"';
在新的cmd.exe
窗口中:
C:\Temp> t Yet another environment variable "This is a test"
答案 2 :(得分:-1)
如果系统调用的参数是标量,系统命令[contested:/ function]将在默认批处理文件上下文(这是系统范围的环境)中启动批处理脚本。它与使用“cmd / c myfile.bat”启动命令基本相同。如果你对system()的参数是一个数组[contested:/ list],你就不会遇到这个问题。请阅读this for more information。