我想创建一个批处理文件,该文件既执行一次命令,又一次执行循环。当循环再次发生时,该命令将不再执行。这是循环的代码:
@echo off
setlocal EnableDelayedExpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
FOR /L %%n in (1,1,10) DO (
call :spinner
ping localhost -n 2 > nul
)
exit /b
:spinner
set /a "spinner=(spinner + 1) %% 4"
set "spinChars=\|/-"
<nul set /p ".=Rebuilding, please wait... !spinChars:~%spinner%,1!!CR!"
exit /b
但是有一个问题:循环将执行,并且仅在命令完成后才执行。而且循环没有超时,因此基本上,它将永远进行循环,直到我按Ctrl + C为止。 谁能帮我这个?如果可以的话,请使上面的代码更好。预先感谢。
答案 0 :(得分:0)
在第一次执行命令时,将变量设置为true值,并在执行该命令之前在该变量中进行条件测试
If not "!EXC!" == "" (Echo First Run) Else (Set "EXC=True")
示例使用延迟扩展,因为它可以在For循环和Label循环中使用。
如果要打破循环,请对Goto:Label使用条件测试
现在您已经提供了更多的问题详细信息,我相信您想要的是这样的东西。
@echo off
setlocal EnableDelayedExpansion
for /f %%a in ('copy /Z "%~dpf0" ^> nul') do set "CR=%%a"
set "spinChars=\|/-"
for /f "delims=#" %%a in ('"prompt #$H# &echo on &for %%b in (1) do rem"') do (
set "BS=%%a"
set "BS=!BS:~0,1!"
)
<nul set/p=Rebuilding, please wait...
FOR /L %%. in () DO (
REM insert conditional testing to break loop Here
set /a "spinner=(spinner + 1) %% 4"
For %%/ in (!Spinner!) Do <nul set /p=%BS%!spinChars:~%%/,1!
)
exit /b
:End_Loop
Echo You have Exited the process
Pause
Exit /B
退格字符的定义来自此post
无论在加载循环中等待什么过程,您都需要某种方法来测试其是否完成。鉴于您尚未详细介绍,我将建议一些选项:
如果您提供有关正在等待的命令/进程的更多详细信息,则可以提供有关条件测试的更好答案。
一种示例方法,该方法在同一窗口中将子例程作为单独的实例运行,并在命令执行完成后使用信号文件与主循环通信:
::: ** Batch Multithreading example by T3RRY ** :::
@Echo Off & CD "%~dp0" :::
:::::::::::::::::::::::::::::::::::::::::::::::::::
::: - Define any Variables to be used by both Environments
Set "spinChars=\|/-"
::: - Test if Thread Two is to be executed
If /I "%~1" == "Thread2" Goto :Thread2
::: - Localise Thread Ones Environment
Setlocal EnableDelayedExpansion
::: - Ensure previous Signal files removed in case program exited incorrectly
Del /Q /F "%TEMP%\CMDrun.log"
Del /Q /F "%TEMP%\CMDend.log"
CLS
::: - Define Backspace Character for Animation
For /F "delims=#" %%a in ('"prompt #$H# &echo on &for %%b in (1) do rem"') do (
Set "BS=%%a"
Set "BS=!BS:~0,1!"
)
<Nul Set/P=Processing, please wait.
:Loop
::: - Launch Thread Two in Same window if Not already Running
::: - Conditional tests on signal files redirect errors to Standard error to prevent erroneous output
::: - when testing occurs at the same time the file is being written to.
(IF Not Exist "%TEMP%\CMDrun.log" Start /B "" "%~F0" Thread2) 2>Nul
::: - Animation To indicate commands in thread one are running. A Loop is used in this example.
Set /A "spinner=(spinner + 1) %% 4"
For %%S in (!Spinner!) Do <Nul Set /P=%BS%!spinChars:~%%S,1!
::: - Exit Thread One once Thread Two has Completed
(IF Exist "%TEMP%\CMDend.log" Goto :End_Loop) 2>Nul
Goto :Loop
:End_Loop
::: - Clean up Signal Files
Echo.
Del /Q /F "%TEMP%\CMDrun.log"
Del /Q /F "%TEMP%\CMDend.log"
Echo Process Complete
Pause
::: - Demonstrate stability of multithreading through repetition
Start "" "%~F0"
Exit
:Thread2
::: Localise Thread Two's Environment
Setlocal EnableDelayedExpansion
>"%TEMP%\CMDrun.log" (Echo running)
::: - Title update to demonstrate commands executed in thread two are running
For /L %%# In (1,1,10000) Do (
Set /a "spinner=(spinner + 1) %% 4"
For %%S in (!Spinner!) Do TITLE !spinChars:~%%S,1! Output %%#
)
>"%TEMP%\CMDend.log" (Echo finished)
::: - Hard exit of Thread Two used to prevent script overflow.
EXIT