2016-11-30 155 views
1

我试图制作一个非常简单的bat文件。批处理文件 - 等待循环中的文件

在for循环中,我调用另一个应用程序为我创建一个文件。当生成该文件时,我想再次执行此操作,直到循环结束。在我再次运行循环之前,我需要等待文件的创建。

我需要使用STARTCALL,因为在文件创建后,我会杀死进程。它不包含在下面的代码中,但它是必需的。

@echo off 

for /L %%i in (1,1,5) do (
    SET filename=fooFile_%%i.txt 
     START /B CMD /C CALL createFile.bat fooFile_%%i.txt 

    :waitfile 
     ECHO waitforfile: %filename% 
     TIMEOUT /T 10 >nul 
     IF EXIST %filename% GOTO FoundIt 
     goto waitfile 

    :FoundIt 
     ECHO Found file %filename% 
) 
ECHO All done! 

而我的createFile.bat。这实际上是另一种应用。但是,下面的代码就足以嘲笑它:

@echo off 

set arg1=%1 
TIMEOUT /T 10 >nul 
copy NUL %arg1% 
ECHO Created file 

电流输出:

waitforfile: 
waitforfile fooFile_1.txt 
    1 file(s) copied. 
Created file 
Found file fooFile_1.txt 
All done! 

正如你可以从输出看到我不能循环使用我的GOTO的工作。我已经看到了这些问题:

Batch file goto not working in for loop

(Windows batch) Goto within if block behaves very strangely

看来,因为它是一个坏主意,被goto的循环相结合。那么我该如何解决我的问题?

+0

有在你的代码的两个问题:1,你错过了使用[延迟扩展(HTTP:// ss64。 com/nt/delayedexpansion.html),尽管在编写*和*时需要这样做,并在代码块中读取相同的变量; 2.'goto:Label'不能在块/循环中使用,因为这会中断块/循环上下文; – aschipfl

+0

@aschipfl - 谢谢。我是新来的蝙蝠文件。我会尝试建议的解决方案。看起来他们都工作。在我接受它作为答案之前,我只需要确定哪种解决方案最适合我的具体问题。 – smoksnes

回答

2

1)要使用可循环中被改变的变量使用EnableDelayedExpansion!var!代替%var%

2)移动:waitfile到子

@echo off 
setlocal EnableDelayedExpansion 

for /L %%i in (1,1,5) do (
    SET filename=fooFile_%%i.txt 
     START /B CMD /C CALL createFile.bat fooFile_%%i.txt 

    call :waitfile "!filename!" 

    ECHO Found file !filename! 
) 
ECHO All done! 
exit /b 0 

:waitfile 
    ECHO waitforfile: %~1 
:waitfile2 
    TIMEOUT /T 10 >nul 
    IF not EXIST "%~1" goto waitfile2 
exit /b 0 
+0

谢谢!接受这个特殊的答案,因为它最适合我的需求,并且与我的其他逻辑非常吻合。其他答案也起作用。 – smoksnes

1
@echo off 

for /L %%i in (1,1,5) do (call :process %%i 
) 
ECHO All done! 

:: rest of mainline code here 

goto :eof 

:process 
SET filename=fooFile_%1.txt 
START /B CMD /C CALL createFile.bat fooFile_%1.txt 

:waitfile 
ECHO waitforfile: %filename% 
TIMEOUT /T 10 >nul 
IF EXIST %filename% GOTO FoundIt 
goto waitfile 

:FoundIt 
ECHO Found file %filename% 
goto :eof 

还有其他问题,您的批处理 - 如果在循环中使用环境变量的更改值,则主要需要delayedexpansion方法。

3
@echo off 
    setlocal enableextensions disabledelayedexpansion 

    for /L %%i in (1,1,5) do for %%f in ("fooFile_%%i.txt") do (
     start /b "" cmd /c createFile.bat "%%~ff" 

     2>nul ( 
      break | for /l %%a in (0) do @(<"%%~ff" exit) || ( 
       echo ...waiting for %%~ff 
       ping -n 5 localhost >nul 
      ) 
     ) 

     echo [%%~ff] found 
    ) 
    ECHO All done! 
  • 为了避免使延迟扩展仅检索改变的变量内的值,将所生成的文件名被包裹(%%f

  • 的等待循环中执行的for替换的参数内一个单独的cmd进程(产生以处理管道),当目标文件可被读取时,该进程将结束。如果文件不可用,<"%%~ff"输入重定向将失败,并且exit命令将不会执行。如果文件可用,则执行exit命令并结束循环。

  • timeout不能与重定向输入(等待代码在管内运行)使用时,它已被替换为一个ping到本地主机

  • 此测试代码使用生成的文件的完整路径( %%~ff是由%%f指向的文件的完整路径)。将其更改为您的需求。

注:仅作参考,用于测试的createFile.bat

@echo off 
    setlocal enableextensions disabledelayedexpansion 

    if "%~1"=="" exit /B 
    >nul timeout /t 3 
    >"%~1" echo testing