2016-07-01 5 views
1

Ich muss ein Programm für jede Zeile in einer Datei ausführen. Ich triggeriere vier Instanzen gleichzeitig. Nach vier Instanzen, einige Zeit warten und eine weitere auslösen. Nach der Wartezeit bricht das Batch-Skript ab.Breakout for Schleife in Batch-Datei bei der Verwendung von

Bitte schlagen Sie vor, wenn ich falsch mache.

for /F "tokens=*" %%J in (%JobListFile%) do (
    SET JobName=%%J 
    echo job name !JobName! 

    if "!JobName!" equ "" (
     echo joblist not found... rerun the script.. 
     REM exit /b 
    ) else (
     :waittofinish 
     for /F "tokens=*" %%a in ('tasklist /fi "IMAGENAME eq dsexport.exe" ^| grep -c "dsexport.exe"') do (SET /A CurrInstances=%%a) 
     echo current instance is !CurrInstances! 
     echo parallelism set to !NoOfParallelInstances! 
     if "!CurrInstances!" gtr "!NoOfParallelInstances!" (
      echo going to wait 
      sleep 5 
      goto waittofinish 
      echo failed to go wait label... 
     ) else (
      echo Exporting job: !JobName! ...............Starting 
      start /b cmd /C "C:/IBM/9.1/InformationServer/Clients/Classic/dsexport.exe /D=%vDomain% /U=%vuserID% /P=%vpassword% /H=%vServer% %vDSProject% /NODEPENDENTS /JOB=!JobName! %tmppath%\!JobName!.dsx" 
      echo. 
      echo. 
     ) 
    ) 

) 

echo script completed... 

exit /b 
+1

Verwenden Sie nicht "Goto" oder Beschriftungen in einem Block (ein Block ist alles zwischen '(' und ')'), es sei denn, Sie möchten den Block absichtlich verlassen. – Stephan

+1

Sie können den gesamten Block beginnend bei ': waittofinish' (also den gesamten Code in der' else'-Klausel von 'if"! JobName! "Equ" "') in eine Unterroutine einfügen und 'call' verwenden; auf diese Weise versteckst du das 'goto' aus dem Kontext der 'for/F %% J'-Schleife ... – aschipfl

+0

Danke Aschipfl. Es funktionierte. Du hast mich gerettet ... Aber fehlt irgendetwas? letzte Zeile wird zweimal ausgeführt? Ich meine für die letzte Zeile in der Datei, Programm wird zweimal ausgeführt .. irgendeine Idee zu diesem Thema? Unterprogramm löst das Programm zum zweiten Mal aus. Wie man es verhindert? – srinath

Antwort

1

goto :Label bricht der Block Kontext eines Codeblocks in Klammern (...); Dies gilt auch für for ... do (...) Schleifen und if ... (...) else (...) Bedingungen.

Um dies zu überwinden, können Sie den Codeabschnitt mit goto und :Label in einem Unterprogramm setzen, da dies den Block Kontext des anrufenden Codeabschnitt von goto, wie dies verbirgt:

for /F "usebackq tokens=*" %%J in ("%JobListFile%") do (
    SET "JobName=%%J" 
    echo job name !JobName! 

    if "!JobName!" equ "" (
     echo joblist not found... rerun the script.. 
     REM exit /b 
    ) else (
     rem /* The `goto` and `:Label` code fragment has been transferred to a subroutine, 
     rem which receives the current value of variable `JobName` as an argument: */ 
     call :waittofinish "!JobName!" 
    ) 

) 

echo script completed... 

exit /b 


:waittofinish JobName 
rem // This subroutine contains the `goto` and `:Label` code fragment so that it does no longer appear inside of a block `(...)`: 
for /F "tokens=*" %%a in ('tasklist /fi "IMAGENAME eq dsexport.exe" ^| grep -c "dsexport.exe"') do (SET /A CurrInstances=%%a) 
echo current instance is !CurrInstances! 
echo parallelism set to !NoOfParallelInstances! 
if "!CurrInstances!" gtr "!NoOfParallelInstances!" (
    echo going to wait 
    sleep 5 
    goto :waittofinish 
    echo failed to go wait label... 
) else (
    echo Exporting job: %~1 ...............Starting 
    rem // Not sure if some arguments should be enclosed in `""` in the next line (but I do not know `dsexport.exe`): 
    start "" /b cmd /C "C:/IBM/9.1/InformationServer/Clients/Classic/dsexport.exe /D=%vDomain% /U=%vuserID% /P=%vpassword% /H=%vServer% %vDSProject% /NODEPENDENTS /JOB=%~1 %tmppath%\%~1.dsx" 
    echo. 
    echo. 
) 
exit /b 

NB: Ich didn Prüfe nicht die Logik deines Skripts, weil ich grep.exe oder dsexport.exe nicht kenne.