smoksnes
smoksnes

Reputation: 10851

Batch file - Wait for file in loop

I'm trying to make a very simple bat-file.

In a for-loop I call another application which will create a file for me. When that file is generated I want to do this again until the loop has finished. I need to wait for the file to be created before I run the loop again.

I need to use START and CALL, because after the file is created I will kill the process. It's not included in the code below, but it's needed.

@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!

And my createFile.bat. This is actually another application. But the code below is enough to mock it:

@echo off

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

Current output:

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

As you can see from the output I can't get the loop to work with my GOTO's. I've seen these questions:

Batch file goto not working in for loop

(Windows batch) Goto within if block behaves very strangely

It seems as it's a bad idéa to combine loops with goto's. So how can I solve my problem?

Upvotes: 3

Views: 6570

Answers (3)

Magoo
Magoo

Reputation: 79983

@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

There are other problems with your batch - mainly delayedexpansion methodology is required if you use the changed value of an environment variable in the loop.

Upvotes: 1

Dmitry Sokolov
Dmitry Sokolov

Reputation: 3180

  1. To use variables that may be changed in loops use EnableDelayedExpansion and !var! instead of %var%

  2. Move :waitfile to a sub

@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

Upvotes: 3

MC ND
MC ND

Reputation: 70923

@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!
  • To avoid enabling delayed expansion only to retrieve the value inside the changed variable, the generated file name is wrapped inside a for replaceable parameter (%%f)

  • The wait loop is executed in a separate cmd process (spawned to handle the pipe) that will end when the target file can be read. If the file is not available the <"%%~ff" input redirection will fail and the exit command will not be executed. If the file is available, then the exit command is executed and the loop ends.

  • As timeout can not be used with a redirected input (wait code is running inside a pipe), it has been replaced with a ping to local host

  • This test code uses full paths for generated files (%%~ff is the full path of the file being pointed by %%f). Change it to your needs.

note: just for reference, the createFile.bat used for testing was

@echo off
    setlocal enableextensions disabledelayedexpansion

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

Upvotes: 3

Related Questions