Почему переменные среды пакетного файла не устанавливаются при запуске из Perl? - PullRequest
0 голосов
/ 12 октября 2009

Я пытаюсь вызвать bat-файл из сценария perl следующим образом:

 system("call D:/SIP/run_$file_idx.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 );

Проблема все еще замечена с системой () все же. Я попробовал предложение Синан в ответах ..

Ответы [ 3 ]

1 голос
/ 12 октября 2009

Дочерние процессы наследуют среду своего родителя. Файл bat должен иметь ту же среду, что и скрипт Perl. Если вы не настроили среду правильно, ваш bat-файл ее не увидит.

Можете ли вы расширить свой ответ, чтобы показать свой контрольный пример, аналогичный тому, что сделал Синан? Хотя вы говорите в своем комментарии, что код прост, это никогда не соответствует действительности. Покажите нам полную программу Perl, которая у вас есть, и полный файл bat, который у вас есть. Не заставляйте нас угадывать или делать много работы, чтобы выяснить, что вы делаете.

Обновление : Теперь, когда вы предоставили некоторый код, начните вырезать из него части, чтобы создать простейший тестовый пример, который все еще показывает проблему. Когда вы исследуете подобные проблемы, перестаньте работать над большим сценарием и напишите небольшой сценарий, который решает проблему, которая, по вашему мнению, возникает. Таким образом, вы изолируете это от всего остального, что вы можете испортить.

0 голосов
/ 12 октября 2009

Обновление 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"
0 голосов
/ 12 октября 2009

Системная команда [contested: / function] запустит ваш пакетный скрипт в контексте пакетного файла по умолчанию (который является общесистемной средой), если ваш параметр для системного вызова - скаляр. По сути, это то же самое, что запуск команды с использованием «cmd / c myfile.bat». Если ваш аргумент system () является массивом [contested: / list], у вас не возникнет этой проблемы. Пожалуйста, прочитайте это для получения дополнительной информации .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...