代码之家  ›  专栏  ›  技术社区  ›  Prabhu. S

为什么从Perl运行时批处理文件的环境变量没有设置?

  •  -1
  • Prabhu. S  · 技术社区  · 16 年前

    我试图从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 );
    

    不过,system()仍然存在这个问题。我在回答者中尝试了西南的建议。。

    3 回复  |  直到 16 年前
        1
  •  1
  •   brian d foy    16 年前

    子进程继承其父进程的环境。bat文件应具有与Perl脚本相同的环境。如果没有正确设置环境,bat文件将看不到它。

    你能扩展你的答案来展示你的测试用例吗,就像Sinan所做的一样?尽管你在评论中说代码很简单,但这绝不是真的。向我们展示您拥有的完整Perl程序和完整的bat文件。不要让我们猜测或做很多工作来弄清楚你在做什么。

    使现代化 :现在您已经提供了一些代码,开始从中删除部分,以生成仍然显示问题的最简单测试用例。当你在调查这类问题时,停止写大剧本,写一个小剧本来练习你认为你遇到的问题。这样一来,你就可以把它与你可能搞砸的其他事情隔离开来。

        2
  •  0
  •   Sinan Ünür    16 年前

    更新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"
    
        3
  •  -1
  •   Marc Gravell    16 年前

    如果系统调用的参数是标量,则系统命令[Confected:/function]将在默认批处理文件上下文(即系统范围的环境)中启动批处理脚本。这与使用“cmd/cmyfile.bat”启动命令基本相同。如果system()的参数是数组[Confected:/list],则不会出现此问题。请阅读 this for more information .