我正在尝试制作一个非常简单的bat文件。
在for循环中,我调用另一个为我创建文件的应用程序。生成该文件时,我想再次执行此操作,直到循环结束。我需要等待在再次运行循环之前创建文件。
我需要使用START
和CALL
,因为在创建文件后我将终止该进程。它不包含在下面的代码中,但它是必需的。
@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 :(得分: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
方法。