在批处理文件中休眠

165

当编写Windows批处理文件以自动化某些操作时,我需要暂停其执行几秒钟(通常在测试/等待循环中,等待进程启动)。当时,我能找到的最佳解决方案使用ping(我不是在开玩笑)来实现所需的效果。我发现了一个更好的写作方法here,其中描述了一个可调用的“wait.bat”,实现如下:

@ping 127.0.0.1 -n 2 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul

您可以在自己的批处理文件中包含对wait.bat的调用,传入要睡眠的秒数。

显然,Windows 2003资源工具包提供了类Unix的sleep命令(终于有了!)。与此同时,对于那些仍在使用Windows XP、Windows 2000或(遗憾地)Windows NT的人来说,是否有更好的方法呢?

我修改了sleep.py脚本中被接受的答案,以便如果没有在命令行上传递任何参数,则默认为一秒钟:

import time, sys

time.sleep(float(sys.argv[1]) if len(sys.argv) > 1 else 1)

微软的下载页面显示Windows 2003资源工具包也适用于XP。 恐怕没有其他选择,只能使用“外部”实用程序来进行等待:XP命令处理器中没有类似的功能。 - GerG
请查看以下两个链接,了解如何在批处理文件中实现等待命令和睡眠命令: - Wael Dalloul
2
你有几个选项 - 使用 ping 命令模拟睡眠,或下载包含 sleep 命令的 Windows 资源工具包。更多详情请参见:批处理文件 SLEEP 命令 - Rudu
http://stackoverflow.com/questions/5437201/how-to-wait-in-a-batch-script/5822491 http://stackoverflow.com/questions/1304738/wait-in-console https://dev59.com/OG445IYBdhLWcg3wWI-L https://dev59.com/23VC5IYBdhLWcg3w2k-I - Chris Moschini
批处理文件停止各种技术的良好总结:https://www.robvanderwoude.com/wait.php - user1934286
显示剩余5条评论
34个回答

2

适用于Windows 2000之后所有版本的最佳解决方案是:

timeout numbersofseconds /nobreak > nul

不适用于XP Pro... 'timeout'不被识别为内部或外部命令、可执行程序或批处理文件。 - martineau

2

有很多方法可以在cmd/batch中实现“休眠”:

我最喜欢的是:

TIMEOUT /NOBREAK 5 >NUL 2>NUL

这将在不输出任何内容的情况下暂停控制台5秒钟。

最常用的方法:

ping localhost -n 5 >NUL 2>NUL

这将尝试5次连接到localhost。由于它托管在您的计算机上,因此它将始终到达主机,因此每秒钟它都会尝试新的连接。 -n标志表示脚本将尝试连接的次数。在这种情况下为5,因此它将持续5秒。

最后一个的变体:

ping 1.1.1.1 -n 5 >nul

这个脚本与上一个脚本相比有一些不同。它不会尝试调用localhost,而是尝试连接到非常快的网站1.1.1.1。该操作将持续5秒钟仅在您有活动互联网连接时。否则,它将需要大约15秒才能完成操作。我不建议使用这种方法。

ping 127.0.0.1 -n 5 >nul

这与示例2(最常用)完全相同。你也可以使用:

ping [::1] -n 5 >nul

相比之下,这里使用IPv6的本地主机版本。

有很多方法可以执行此操作。然而,我更喜欢Windows Vista及更高版本的方法1和早期操作系统中最常用的方法(方法2)。


2

例如,使用命令行Python,运行时间为6.5秒:

python -c "import time;time.sleep(6.5)"

虽然更短,但这是已接受答案的重复。 - Peter Mortensen
@Peter Mortensen:它还可以让你轻松地将所有东西放入一个批处理文件的单行中。 - martineau

1

我对这个印象深刻:

http://www.computerhope.com/batch.htm#02

choice /n /c y /d y /t 5 > NUL

从技术上讲,您正在告诉choice命令仅接受y。它默认为y,在5秒内执行此操作,不显示提示,并将其说的任何内容转储到NUL(例如Linux上的空终端)。

3
我在此重申一下:我完全不推荐这样做。据我所知,在我使用的“CHOICE”版本中,如果有人在等待期间按键(有时不耐烦的人会这样做),那么“choice”将读取一个输入,对于错误的输入会发出系统蜂鸣声并停止倒计时,因此它会挂起,除非他们按Y。如果他们碰巧按下Y,那么选择就结束了,而不是等待5秒。此外,这个选项使用了非常奇怪的Vista语法。正常的选择命令使用CHOICE /T:Y,5 > NUL,并且旧版本中没有/D标志。如果您正在使用Vista,请使用“TIMEOUT”命令。 - Coding With Style

1

关于这个问题,有很多答案提到了使用ping命令,但是大部分都指向回环地址或者现在被视为DNS有效地址的地址。

相反,你应该使用一个专门用于文档记录的TEST-NET IP地址,根据IETF的规定。(在这里查看更多信息

下面是一个完全注释的批处理脚本,演示了如何使用ping函数进行睡眠操作:

@echo off
:: turns off command-echoing

echo/Script will now wait for 2.5 seconds & echo/
:: prints a line followed by a linebreak

call:sleep 2500
:: waits for two-and-a-half seconds (2500 milliseconds)

echo/Done! Press any key to continue ... & pause >NUL
:: prints a line and pauses

goto:EOF
:: prevents the batch file from executing functions beyond this point


::--FUNCTIONS--::

:SLEEP
:: call this function with the time to wait (in milliseconds)

ping 203.0.113.0 -n 1 -w "%~1" >NUL
:: 203.0.113.0 = TEST-NET-3 reserved IP; -n = ping count; -w = timeout

goto:EOF
:: ends the call subroutine

当然,如果您不想创建函数,也可以直接使用该命令:
ping 203.0.113.0 -n 1 -w timeInMilliseconds >NUL


1
你也可以使用.vbs文件来进行特定的超时操作:
下面的代码创建了.vbs文件。将其放置在批处理代码的顶部附近:
echo WScript.sleep WScript.Arguments(0) >"%cd%\sleeper.vbs"

下面的代码打开 .vbs 文件并指定等待时间:
start /WAIT "" "%cd%\sleeper.vbs" "1000"

在上述代码中,“1000”是以毫秒为单位发送到.vbs文件的时间延迟值,例如,1000ms = 1s。您可以更改此部分的长度。

下面的代码在您完成后删除.vbs文件。将其放在批处理文件的末尾:

del /f /q "%cd%\sleeper.vbs"

这里是所有代码的完整版本,便于复制:
echo WScript.sleep WScript.Arguments(0) >"%cd%\sleeper.vbs"
start /WAIT "" "%cd%\sleeper.vbs" "1000"
del /f /q "%cd%\sleeper.vbs"

1
路径ping.exe可以睡眠少于一秒钟。
@echo off
setlocal EnableDelayedExpansion 
echo !TIME! & pathping localhost -n -q 1 -p %~1 2>&1 > nul & echo !TIME!

.

> sleep 10
17:01:33,57
17:01:33,60

> sleep 20
17:03:56,54
17:03:56,58

> sleep 50
17:04:30,80
17:04:30,87

> sleep 100
17:07:06,12
17:07:06,25

> sleep 200
17:07:08,42
17:07:08,64

> sleep 500
17:07:11,05
17:07:11,57

> sleep 800
17:07:18,98
17:07:19,81

> sleep 1000
17:07:22,61
17:07:23,62

> sleep 1500
17:07:27,55
17:07:29,06

1

如果您安装了Node.js,可以尝试以下代码(仅供娱乐):

node -e 'setTimeout(a => a, 5000)'

休眠5秒钟。它适用于使用Node v12.14.0的Mac。


以下是使用 await 的版本:node --input-type=module -e "await new Promise(resolve=>setTimeout(resolve, 5000))"(是的,楼上的更好,哈哈) - Venryx

0

从Windows Vista开始,你可以使用TIMEOUTSLEEP命令,但要在Windows XP或Windows Server 2003上使用它们,你需要Windows Server 2003资源工具包

这里有一个很好的睡眠替代方案概述(ping方法最流行,因为它适用于每台Windows机器),但还有(至少)一种未被提及的方法,即(滥用)W32TM(时间服务)命令:

w32tm /stripchart /computer:localhost /period:1 /dataonly /samples:N  >nul 2>&1

在这里,您应该将N替换为您想要暂停的秒数。此外,它将在没有先决条件的情况下在每个Windows系统上运行。

Typeperf也可以使用:

typeperf "\System\Processor Queue Length" -si N -sc 1 >nul

使用mshta和javascript(可用于小于一秒的睡眠):

start "" /wait /min /realtime mshta "javascript:setTimeout(function(){close();},5000)"

这应该更加精确(等待不到一秒钟)- 依赖于.net的自编译可执行文件:

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal
::del %~n0.exe /q /f
::
:: For precision better call this like
:: call waitMS 500
:: in order to skip compilation in case there's already built .exe
:: as without pointed extension first the .exe will be called due to the ordering in PATEXT variable
::
::
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /w:0 /out:"%~n0.exe" "%~dpsfnx0"
)


%~n0.exe %*

endlocal & exit /b %errorlevel%


*/


import System;
import System.Threading;

var arguments:String[] = Environment.GetCommandLineArgs();
function printHelp(){
    Console.WriteLine(arguments[0]+" N");
    Console.WriteLine(" N - milliseconds to wait");
    Environment.Exit(0);    
}

if(arguments.length<2){
    printHelp();
}

try{
    var wait:Int32=Int32.Parse(arguments[1]);
    System.Threading.Thread.Sleep(wait);
}catch(err){
    Console.WriteLine('Invalid Number passed');
    Environment.Exit(1);
}

0

你可以通过将“暂停”消息放在标题栏中来使其更加引人注目:

@ECHO off
SET TITLETEXT=Sleep
TITLE %TITLETEXT%
CALL :sleep 5
GOTO :END
:: Function Section
:sleep ARG
ECHO Pausing...
FOR /l %%a in (%~1,-1,1) DO (TITLE Script %TITLETEXT% -- time left^
 %%as&PING.exe -n 2 -w 1000 127.1>NUL)
EXIT /B 0
:: End of script
:END
pause
::this is EOF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接