使用cmd循环执行命令

时间:2020-05-09 12:51:36

标签: batch-file

我想创建一个批处理文件,该文件既执行一次命令,又一次执行循环。当循环再次发生时,该命令将不再执行。这是循环的代码:

@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为止。 谁能帮我这个?如果可以的话,请使上面的代码更好。预先感谢。

1 个答案:

答案 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