2017-10-04 89 views
3

我有一个SSIS作业在异步执行的批处理文件中运行。带嵌套循环的批处理文件中的作用域问题

我需要知道SSIS作业完成输出一堆PDF和XLS文件时。

这些文件出现在两个目录中,即PDF首先是XLS。

我选择编写第二个批处理文件,在SSIS作业退出后等待一会儿,然后检查最后写在目录中的文件是否已经存在了3分钟,在观察之后,这是一个充足的作业写入文件的时间间隔。

问题是:如果内循环迭代多次,外循环永远不会运行,这似乎表明第二次MYPATH被声明,n的值被foobarred,但这不可能是真的,因为脚本正在返回1,而不是在检查Arr [badval]时退出。

@ECHO OFF 

REM SSIS process is asyncronous, and executes in background. Problematic for 
REM DAG, which relies on exit code to understand process. 
REM Check for "last file written" in output directories every N seconds. 
REM It's a good bet we are done when they match. 

@setlocal enabledelayedexpansion 

REM "sleep" wait for non-existent command to complete 
waitfor ragnarok /t 180>NUL 2>&1 

set Arr[0]=E:\pdf_output 
set Arr[1]=E:\xls_output 

for /l %%n in (0,1,2) do (

    if defined Arr[%%n] (
     REM set value for path within loop or scope will bite you 
     set MYPATH=!Arr[%%n]! 
     echo Checking file ages in !MYPATH!. 
    ) else (
     echo Done 
     EXIT /B 0 
    ) 

    :while1 
     REM don't put a blank line here, it throws a syntax error 
     FOR /F "delims=|" %%I IN ('DIR !MYPATH! /B /O:D') DO SET FILE1=%%I 

     REM "sleep" use ping for delay, since waitfor will break loop 
     arp -s 192.168.1.254 >nul 
     ipconfig /flushdns >nul 
     ping localhost -n 180 >nul 

     FOR /F "delims=|" %%I IN ('DIR !MYPATH! /B /O:D') DO SET FILE2=%%I 

     if NOT "!FILE1!" == "!FILE2!" (
      goto :while1 
     ) 
) 
endlocal 
REM Something is wrong, return 1 to stop DAG and invite inspection. 
exit /B 1 
+0

你不能打破一个'FOR/L'命令,你不应该使用一个'在'FOR'命令内的GOTO。 – Squashman

+0

问题是'goto:while1',因为它打破了它所嵌套的* all *循环的上下文环境;所以你必须把整个WHILE循环结构放到一个子例程中,并通过['call'](http://ss64.com/nt/call.html)调用它... – aschipfl

+0

@aschipfl:你的建议似乎已经做到了。感谢您的澄清。 –

回答

2

打破while循环到子程序@aschipfl建议似乎做的伎俩:

@ECHO OFF 

REM SSIS process is asyncronous, and executes in background. Problematic for 
REM DAG, which relies on exit code to understand process. 
REM Check for "last file written" in output directories every N seconds. 
REM It's a good bet we are done when they match. 

@setlocal enabledelayedexpansion 

REM "sleep" wait for non-existent command to complete 
waitfor ragnarok /t 120>NUL 2>&1 

set Arr[0]=E:\pdf_output 
set Arr[1]=E:\xls_output 

for /l %%n in (0,1,2) do (

    if defined Arr[%%n] (
     REM set value for path within loop or scope will bite you 
     set MYPATH=!Arr[%%n]! 
     echo Checking file ages in !MYPATH!. 
     CALL :checkfiles 
    ) else (
     echo Done 
     goto :NormalExit 
    ) 
) 

:checkfiles 
    :while1 
     REM don't put a blank line here, it throws a syntax error 
     FOR /F "delims=|" %%I IN ('DIR !MYPATH! /B /O:D') DO SET FILE1=%%I 

     REM "sleep" use ping for delay, since waitfor will break loop 
     arp -s 192.168.1.254 >nul 
     ipconfig /flushdns >nul 
     ping localhost -n 120 >nul 

     FOR /F "delims=|" %%I IN ('DIR !MYPATH! /B /O:D') DO SET FILE2=%%I 

     if NOT "!FILE1!" == "!FILE2!" (
      goto :while1 
     ) 
endlocal 

:NormalExit 
    exit /B 0 

REM Something is wrong, return 1 to stop DAG and invite inspection. 
exit /B 1