批处理文件 - 等待文件循环

时间:2016-11-30 08:22:22

标签: batch-file

我正在尝试制作一个非常简单的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组合起来似乎是一个糟糕的习惯。那我怎么解决我的问题呢?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分: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!
  • 为避免启用延迟扩展仅检索已更改变量中的值,生成的文件名将包含在for可替换参数(%%f

  • 等待循环在单独的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

答案 2 :(得分: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方法。