复制CMD"超时"倒计时以在自定义回显中打印

Has*_*him 0 windows for-loop cmd batch-file

我已经整理了一个供最终用户使用的批处理脚本.除了让用户认为某些事情正在发生之外没有特定的功能目的,我想让脚本在继续执行之前等待几秒钟.在Vista及更高版本中,这可以通过以下方式轻松完成TIMEOUT /3.

但是,我想TIMEOUT用自己的自定义输出替换命令的默认输出,同时保留其倒计时功能.据我所知,TIMEOUT也没有等效PINGSLEEP方法支持这一点,所以这必须手动完成,我想知道最简单的方法是什么.

J.B*_*oby 7

所有TIMEOUT这一切都是从t你给它等待到0 的时间算起来的.所以你可以通过以下方式实现同​​样的目的:

  1. 打印东西(t如果你想要的话)
  2. 等一下
  3. 打印东西(带t-1)
  4. 等一秒钟......

您可能希望在一行上打印所有内容.您可以通过在一行末尾打印回车来实现:效果将是您将能够覆盖该行(内容不会被完全删除,只是被覆盖).这是一个获得带有延迟扩展的回车字符的技巧:

FOR /F %%a IN ('copy /Z "%~dpf0" nul') DO set "carret=%%a"
Run Code Online (Sandbox Code Playgroud)

这将把回车符放在carret变量中.

现在打印...您将无法使用echo打印,它仍将以回车符和换行符结束每个输入(您将在每个输出结束后echo返回一个新行并且回车将没用了).所以你必须使用set /p.它允许您在没有回车和换行符的情况下进行打印:set /p =print something<nul.

所以你的批次看起来像这样:

@echo off
SetLocal EnableDelayedExpansion

REM countdown of 5 seconds
set count=5

REM prepare carriage return
FOR /F %%a IN ('copy /Z "%~dpf0" nul') DO set "carret=%%a"

:ONE_SEC
REM print message
set /p =%count% seconds to go...!carret!<nul
REM wait one sec
ping -n 2 127.0.0.1 > nul 2>&1
REM decrement
set /a count-=1
IF %count% GTR 0 goto :ONE_SEC

REM last print, now you can use echo but don't forget: you have to override each character of the previous print! so fill all remaining place with whitespaces
echo Done waiting...   
REM  X seconds to go...

EndLocal
exit /b 0
Run Code Online (Sandbox Code Playgroud)

编辑:因为回车只允许覆盖以前打印的行,如果回车后打印的内容不能完全覆盖之前打印的内容,则必须添加空格.这是最后一个发生的事情echo:Done waiting...X seconds to go...它短,它不会完全覆盖它:

Done waiting...   
X seconds to go...
   from here ->   <- untill here: characters that won't be overwritten
Run Code Online (Sandbox Code Playgroud)

它仅覆盖到的邻go所以小圆点...的的X seconds to go...意志仍然可以看到,你会落得

Done waiting......
Run Code Online (Sandbox Code Playgroud)

解决方案是使用空格(3个超过字符 - > 3个空格)覆盖那些超出字符的字符.所以最后的回声应该是

echo Done waiting...<SPACE><SPACE><SPACE>
Run Code Online (Sandbox Code Playgroud)

替换<SPACE>为真实的空白.我在上面的代码中也添加了它,但它不可见.

另外,我要感谢@LotPing回答让我意识到你实际上可以从标签取代一切:ONE_SECIF...goto ONE_SEC一个FOR /L像他那样:

FOR /L %%S IN (%count%, -1, 1) DO (
    set /p =%%S seconds to go...!carret!<nul
    ping -n 2 127.0.0.1 > nul 2>&1
)
Run Code Online (Sandbox Code Playgroud)

timeout为等待取代了"不太稳定" .timeout /N会在几秒钟N-1N几秒钟之间等待,对于大型会很好N但是N=1会导致一些问题.(等待0.3秒代替1的效果与149.3而不是150例如不同).set /p我不需要循环之前的额外功能.