2009-10-12 4 views
-1

Je suis en train d'appeler un fichier de chauve-souris à partir d'un script Perl comme suit:Pourquoi les variables d'environnement d'un fichier de commandes ne sont-elles pas définies lors de l'exécution de Perl?

system("call D:/SIP/run_$file_idx.bat"); 

Cependant, je constate que les variables d'environnement dans la chauve-souris ne parviennent pas à se résoudre. Si j'exécute le fichier bat séparément de l'invite de commande, cela fonctionne.

Est-ce que system() crée un nouvel environnement et y exécute un fichier bat? Qu'est-ce qui me manque?

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\"); 

Et le fichier batch est:

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 

Solution possible:

En utilisant exec et écrit spécifiquement l'ENV dans le fichier de chauve-souris m'a donné une solution de contournement:

print OUT map { "set $_=$ENV{$_}\n" } 
      qw(path USERPROFILE USERNAME ProgramFiles ComSpec APPDATA); 

Le problème est toujours vu avec system() cependant. J'ai essayé la suggestion de Sinan dans les répondeurs ..

+1

exécutez-vous le code avec le même utilisateur/login les deux fois? – lexu

+0

Lexu, Oui, je lance le script avec le même utilisateur/login les fois les –

+1

sont les variables d'environnement visibles depuis perl? my $ fooBar = $ ENV {VotreVariableName}; imprime $ fooBar; – lexu

Répondre

-1

La commande système [contestée:/function] lancera votre script de traitement par lots dans le contexte de fichier de commandes par défaut (qui est l'environnement à l'échelle du système), si votre paramètre à l'appel système est un scalaire. C'est fondamentalement le même que de lancer la commande en utilisant "cmd/c myfile.bat". Si votre argument à system() est un tableau [contesté:/list], vous n'aurez pas ce problème. S'il vous plaît lire this for more information.

+0

Je ne vois pas l'intérêt de se lier à un site qui donne des informations incomplètes qui n'ont absolument rien à voir avec le problème de l'OP, à part leur donner du jus de fruit et augmenter leurs revenus publicitaires. Auparavant, j'avais dirigé le lien vers la documentation officielle de Perl. Maintenant, signaler votre message comme spam. –

+0

Sinian, êtes-vous dirigé vers un site de spam en cliquant sur ce lien, ou un aperçu de la façon de démarrer les commandes externes dans perl? Le site n'est peut-être pas à votre goût, pas le meilleur ou même correct - mais vous devriez quand même respecter ma réponse (et la déprécier, la commenter, comme c'est le cas, si vous le souhaitez). Quant à l'exactitude, le bug réel semble être qu'il utilise 'start' dans son code (ce qui n'était pas montré dans la question d'origine). –

+0

En outre, nofollow est utilisé sur tous les liens. Il n'y a pas de jus de google à rassembler ici. –

0

Mise à jour 2: Regardons de plus près à votre appel system:

system(\"start $ENV{'IPSL_TESTCASES_PATH'}SIP\\run_$file_idx.bat\"); 

Cela devrait être erreur de syntaxe et votre script ne doit pas même être en mesure d'invoquer le fichier batch. Essayez

system(qq{start $ENV{IPSL_TESTCASES_PATH}SIP\\run_$file_idx.bat\\}); 

Mise à jour 1: En regardant le code affiché, vous utilisez start dans l'appel système. Cela démarre un nouveau processus cmd.exe et que cmd.exe restera longtemps après la fin de votre script. Cependant, je n'observe toujours pas le comportement que vous décrivez et je vais regarder votre décharge de code de plus près.

 
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"'; 

Dans une nouvelle fenêtre cmd.exe:

 
C:\Temp> t 
Yet another environment variable 
"This is a test" 
1

processus enfants héritent de l'environnement de leur parent. Le fichier bat doit avoir le même environnement que le script Perl. Si vous n'avez pas configuré l'environnement correctement, votre fichier bat ne le verra pas. Pouvez-vous développer votre réponse pour montrer votre cas de test, semblable à ce que Sinan a fait? Bien que vous disiez dans votre commentaire que le code est simple, ce n'est jamais vrai. Montrez-nous le programme Perl complet que vous avez et le fichier bat complet que vous avez. Ne nous faites pas deviner ou faire beaucoup de travail pour comprendre ce que vous faites.

Mise à jour: Maintenant que vous avez fourni du code, commencez à en découper des parties pour créer le cas de test le plus simple qui présente toujours le problème. Lorsque vous étudiez ce genre de problèmes, arrêtez de travailler sur le gros script et écrivez un petit script qui résout le problème que vous pensez avoir. De cette façon, vous l'isolez de tout ce que vous pourriez vous tromper.

Questions connexes