2016-11-30 157 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