When writing a batch file to automate something on a Windows box, I've needed to pause its execution for several seconds (usually in a test/wait loop, waiting for a process to start). At the time, the best solution I could find uses ping (I kid you not) to achieve the desired effect. I've found a better write-up of ithere, which describes a callable "wait.bat", implemented as follows:
@ping 127.0.0.1 -n 2 -w 1000 > nul@ping 127.0.0.1 -n %1% -w 1000> nulYou can then include calls to wait.bat in your own batch file, passing in the number of seconds to sleep.
Apparently the Windows 2003 Resource Kit provides a Unix-like sleep command (at last!). In the meantime, for those of us still using Windows XP, Windows 2000 or (sadly)Windows NT, is there a better way?
I modified thesleep.py script in theaccepted answer, so that it defaults to one second if no arguments are passed on the command line:
import time, systime.sleep(float(sys.argv[1]) if len(sys.argv) > 1 else 1)- The Microsoftdownload page of the Windows 2003 Resource Kit indicates that it also works for XP. I'm afraid there is no other choice but to use an 'external' utility to do the waiting: there is nothing like this built into the XP command processor.GerG– GerG2008-10-03 09:22:15 +00:00CommentedOct 3, 2008 at 9:22
- The 2003 server resource kit works with Windows XP (and probably with w2k)Martin Beckett– Martin Beckett2009-07-07 14:41:40 +00:00CommentedJul 7, 2009 at 14:41
- I faced the same problem in the past, and used ping myself (with a remark above clearly documenting that I realize this is stupid :) ).Jack Leow– Jack Leow2009-07-07 14:47:33 +00:00CommentedJul 7, 2009 at 14:47
- Check:Implementing the WAIT Command in a Batch FileBatch file SLEEP CommandWael Dalloul– Wael Dalloul2009-08-20 08:28:09 +00:00CommentedAug 20, 2009 at 8:28
- 2You have a couple of options - emulate a sleep with the
pingcommand, or download the windows resource kit which includes asleepcommand. More details here:Batch file SLEEP CommandRudu– Rudu2011-03-25 19:30:22 +00:00CommentedMar 25, 2011 at 19:30
34 Answers34
Thetimeout command is available from Windows Vista onwards:
c:\> timeout /?TIMEOUT [/T] timeout [/NOBREAK]Description: This utility accepts a timeout parameter to wait for the specified time period (in seconds) or until any key is pressed. It also accepts a parameter to ignore the key press.Parameter List: /T timeout Specifies the number of seconds to wait. Valid range is -1 to 99999 seconds. /NOBREAK Ignore key presses and wait specified time. /? Displays this help message.NOTE: A timeout value of -1 means to wait indefinitely for a key press.Examples: TIMEOUT /? TIMEOUT /T 10 TIMEOUT /T 300 /NOBREAK TIMEOUT /T -1Usage, sleep for 2 seconds:
c:\> timeout /T 2Usage, sleep then do something else same line:
c:\> timeout /T 2 && echo hiNote: It does not work with input redirection - trivial example:
C:\>echo 1 | timeout /t 1 /nobreakERROR: Input redirection is not supported, exiting the process immediately.7 Comments
Using theping method as outlined is how I do it when I can't (or don't want to) add more executables or install any other software.
You should be pinging something that isn't there, and using the-w flag so that it fails after that amount of time, not pinging something thatis there (like localhost)-n times. This allows you to handle time less than a second, and I think it's slightly more accurate.
e.g.
(test that 1.1.1.1 isn't taken)
ECHO Waiting 15 secondsPING 1.1.1.1 -n 1 -w 15000 > NUL orPING -n 15 -w 1000 127.1 >NUL3 Comments
PING: transmit failed. General failure.1.1.1.1 is taken by CloudFlare, so this will not wait 15s but around some ms.UPDATE
Thetimeout command, available from Windows Vista and onwards should be the command used, as described in anotheranswer to this question. What follows here is anold answer.
Old answer
If you have Python installed, or don't mind installing it (it has other uses too :), just create the followingsleep.py script and add it somewhere in your PATH:
import time, systime.sleep(float(sys.argv[1]))It will allow sub-second pauses (for example, 1.5 sec, 0.1, etc.), should you have such a need. If you want to call it assleep rather thansleep.py, then you can add the.PY extension to your PATHEXT environment variable. On Windows XP, you can edit it in:
My Computer → Properties (menu) → Advanced (tab) → Environment Variables (button) → System variables (frame)
3 Comments
SLEEP.exe is included in most Resource Kits e.g.The Windows Server 2003 Resource Kit which can be installed on Windows XP too.
Usage: sleep time-to-sleep-in-seconds sleep [-m] time-to-sleep-in-milliseconds sleep [-c] commited-memory ratio (1%-100%)Comments
I disagree with the answers I found here.
I use the following method entirely based on Windows XP capabilities to do a delay in a batch file:
DELAY.BAT:
@ECHO OFFREM DELAY secondsREM GET ENDING SECONDFOR /F "TOKENS=1-3 DELIMS=:." %%A IN ("%TIME%") DO SET /A H=%%A, M=1%%B%%100, S=1%%C%%100, ENDING=(H*60+M)*60+S+%1REM WAIT FOR SUCH A SECOND:WAITFOR /F "TOKENS=1-3 DELIMS=:." %%A IN ("%TIME%") DO SET /A H=%%A, M=1%%B%%100, S=1%%C%%100, CURRENT=(H*60+M)*60+SIF %CURRENT% LSS %ENDING% GOTO WAITYou may also insert the day in the calculation so the method also works when the delay interval pass over midnight.
14 Comments
TIME command.%TIME% use a comma to separate the centiseconds, instead of a point! Just add a comma inDELIMS=:.,"...I faced a similar problem, but I just knocked up a very short C++ console application to do the same thing. Just runMySleep.exe 1000 - perhaps easier than downloading/installing the whole resource kit.
#include <tchar.h>#include <stdio.h>#include "Windows.h"int _tmain(int argc, _TCHAR* argv[]){ if (argc == 2) { _tprintf(_T("Sleeping for %s ms\n"), argv[1]); Sleep(_tstoi(argv[1])); } else { _tprintf(_T("Wrong number of arguments.\n")); } return 0;}Comments
You can use ping:
ping 127.0.0.1 -n 11 -w 1000 >nul: 2>nul:It will wait 10 seconds.
The reason you have to use 11 is because the first ping goes out immediately, not after one second. The number should always be one more than the number of seconds you want to wait.
Keep in mind that the purpose of the-w is not to control how often packets are sent, it's to ensure that you wait nomore than some time in the event that there are network problems. There are unlikely to be problems if you're pinging 127.0.0.1 so this is probably moot.
Theping command on its own will normally send one packet per second. This is not actually documented in the Windows docs but it appears to follow the same rules as the Linux version (where it is documented).
8 Comments
-w was the timeout (though I admit some may infer that due to my lack of clarity), it's actually used to limit the cycle time where there are network problems which would cause each cycle to takemore than its allocated second. I've added a paragraph to the end to clarify this.Over at Server Fault,a similar question was asked, and the solution there was:
choice /d y /t 5 > nul5 Comments
CHOICE versions I know, if someone hits a button while waiting, which impatient folks do sometimes, then choice will register an input, give a system beep for a bad input, and halt the countdown timer, which means it will hang there unless they push N or Y. And if they just happen to push one of those two, then the choice ends right there instead of waiting for 5. Also, this choice is using really weird Vista syntax. All the normal choice commands would instead useCHOICE /T:Y,5 > NUL for that. There is no/D flag in the old versions./C:YN or just/C:Y, this is not going to work when someone happens to have, say, a Swedish choice command which will probably do a [J,N] by default. So this is mired in all sorts of trouble.You could use the Windowscscript WSH layer and thiswait.js JavaScript file:
if (WScript.Arguments.Count() == 1) WScript.Sleep(WScript.Arguments(0)*1000);else WScript.Echo("Usage: cscript wait.js seconds");1 Comment
There is a better way to sleep using ping. You'll want to ping an address that does not exist, so you can specify a timeout with millisecond precision. Luckily, such an address is defined in a standard (RFC 3330), and it is192.0.2.x. This is not made-up, it really is an address with the sole purpose of not-existing. To be clear, this applies even in local networks.
192.0.2.0/24 - This block is assigned as "TEST-NET" for use indocumentation and example code. It is often used in conjunction withdomain names example.com or example.net in vendor and protocoldocumentation. Addresses within this block should not appear on thepublic Internet.
To sleep for 123 milliseconds, useping 192.0.2.1 -n 1 -w 123 >nul
Update: As per the comments, there is also127.255.255.255.
5 Comments
-n parameter.ping 192.0.2.1 on this Windows PC and it can be seen that Windows TCP/IP stack replies on the echo requests. How many people know that 192.0.2.0/24 should not be used for a static IPv4 address?127.255.255.255 due to it being a broadcast loopback address in Windows which is already assigned to by default (You can confirm this by runningroute print in cmd and looking through the IPv4 route table it prints).Depending on your compatibility needs, either useping:
ping -n <numberofseconds+1> localhost >nul 2>&1e.g. to wait 5 seconds, use
ping -n 6 localhost >nul 2>&1or on Windows 7 or later usetimeout:
timeout 6 >nul1 Comment
-w is in milliseconds,-n is just the number of times to ping and the default time between pings is a second.If you've gotPowerShell on your system, you can just execute this command:
powershell -command "Start-Sleep -s 1"Edit: frommy answer on a similar thread, people raised an issue where the amount of time powershell takes to start is significant compared to how long you're trying to wait for. If the accuracy of the wait time is important (ie a second or two extra delay is not acceptable), you can use this approach:
powershell -command "$sleepUntil = [DateTime]::Parse('%date% %time%').AddSeconds(5); $sleepDuration = $sleepUntil.Subtract((get-date)).TotalMilliseconds; start-sleep -m $sleepDuration"This takes the time when the windows command was issued, and the powershell script sleeps until 5 seconds after that time. So as long as powershell takes less time to start than your sleep duration, this approach will work (it's around 600ms on my machine).
2 Comments
-noprofile your powershell will start decently fast no matter how much extra you've added to your user profile.-Milliseconds can be used for that.timeout /t <seconds> <options>For example, to make the script perform a non-uninterruptible 2-second wait:
timeout /t 2 /nobreak >NULWhich means the script will wait 2 seconds before continuing.
By default, a keystroke will interrupt the timeout, so use the/nobreak switch if you don't want the user to be able to interrupt (cancel) the wait. Furthermore, the timeout will provide per-second notifications to notify the user how long is left to wait; this can be removed by piping the command toNUL.
edit: As@martineaupoints out in the comments, thetimeout command is only available on Windows 7 and above. Furthermore, theping command uses less processor time thantimeout. I still believe in usingtimeout where possible, though, as it is more readable than theping 'hack'. Read morehere.
1 Comment
ping approach uses less processor time.Just put this in your batch file where you want the wait.
@ping 127.0.0.1 -n 11 -w 1000 > null2 Comments
In Notepad, write:
@echo offset /a WAITTIME=%1+1PING 127.0.0.1 -n %WAITTIME% > nulgoto:eofNow save as wait.bat in the folder C:\WINDOWS\System32,then whenever you want to wait, use:
CALL WAIT.bat <whole number of seconds without quotes>3 Comments
ping something not just once, and use the-w Timeout option for the delay-time in milliseconds rather than the-n Count whole number-of-retries option.-w Timeout may be better, but i made sure it pings one more time than the time entered.TheResource Kit has always included this. At least since Windows 2000.
Also, the Cygwin package has asleep - plop that into your PATH and include thecygwin.dll (or whatever it's called) and way to go!
2 Comments
Even more lightweight than the Python solution is a Perlone-liner.
To sleep for seven seconds put this in the BAT script:
perl -e "sleep 7"This solution only provides a resolution of one second.
If you need higher resolution then use the Time::HiResmodule from CPAN. It providesusleep() which sleeps inmicroseconds andnanosleep() which sleeps in nanoseconds(both functions takes only integer arguments). See theStack Overflow questionHow do I sleep for a millisecond in Perl? for further details.
I have usedActivePerl for many years. It is very easy toinstall.
2 Comments
The usage ofping is good, as long as you just want to "wait for a bit". This since you are dependent on other functions underneath, like your network working and the fact that there is nothing answering on 127.0.0.1. ;-) Maybe it is not very likely it fails, but it is not impossible...
If you want to be sure that you are waiting exactly the specified time, you should use thesleep functionality (which also have the advantage that it doesn't use CPU power or wait for a network to become ready).
To find an already made executable for sleep is the most convenient way. Just drop it into your Windows folder or any other part of your standard path and it is always available.
Otherwise, if you have a compiling environment you can easily make one yourself.TheSleep function is available inkernel32.dll, so you just need to use that one. :-)For VB / VBA declare the following in the beginning of your source to declare a sleep function:
private Declare Sub Sleep Lib "kernel32" Alias "Sleep" (byval dwMilliseconds as Long)For C#:
[DllImport("kernel32.dll")]static extern void Sleep(uint dwMilliseconds);You'll find here more about this functionality (available since Windows 2000) inSleep function (MSDN).
In standard C,sleep() is included in the standard library and in Microsoft's Visual Studio C the function is namedSleep(), if memory serves me. ;-) Those two takes the argument in seconds, not in milliseconds as the two previous declarations.
2 Comments
I likeAacini's response. I added to it to handle the day and also enable it to handlecentiseconds (%TIME% outputsH:MM:SS.CC):
:delaySET DELAYINPUT=%1SET /A DAYS=DELAYINPUT/8640000SET /A DELAYINPUT=DELAYINPUT-(DAYS*864000)::Get ending centisecond (10 milliseconds)FOR /F "tokens=1-4 delims=:." %%A IN ("%TIME%") DO SET /A H=%%A, M=1%%B%%100, S=1%%C%%100, X=1%%D%%100, ENDING=((H*60+M)*60+S)*100+X+DELAYINPUTSET /A DAYS=DAYS+ENDING/8640000SET /A ENDING=ENDING-(DAYS*864000)::Wait for such a centisecond:delay_waitFOR /F "tokens=1-4 delims=:." %%A IN ("%TIME%") DO SET /A H=%%A, M=1%%B%%100, S=1%%C%%100, X=1%%D%%100, CURRENT=((H*60+M)*60+S)*100+XIF DEFINED LASTCURRENT IF %CURRENT% LSS %LASTCURRENT% SET /A DAYS=DAYS-1SET LASTCURRENT=%CURRENT%IF %CURRENT% LSS %ENDING% GOTO delay_waitIF %DAYS% GTR 0 GOTO delay_waitGOTO :EOFComments
I have been using this C# sleep program. It might be more convenient for you if C# is your preferred language:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace sleep{ class Program { static void Main(string[] args) { if (args.Length == 1) { double time = Double.Parse(args[0]); Thread.Sleep((int)(time*1000)); } else { Console.WriteLine("Usage: sleep <seconds>\nExample: sleep 10"); } } }}Comments
Or command line Python, for example, for 6 and a half seconds:
python -c "import time;time.sleep(6.5)"2 Comments
The best solution that should work on all Windows versions after Windows 2000 would be:
timeout numbersofseconds /nobreak > nul1 Comment
'timeout' is not recognized as an internal or external command, operable program or batch file.There are lots of ways to accomplish a 'sleep' in cmd/batch:
My favourite one:
TIMEOUT /NOBREAK 5 >NUL 2>NULThis will stop the console for 5 seconds, without any output.
Most used:
ping localhost -n 5 >NUL 2>NULThis will try to make a connection tolocalhost 5 times. Since it is hosted on your computer, it will always reach the host, so every second it will try the new every second. The-n flag indicates how many times the script will try the connection. In this case is 5, so it will last 5 seconds.
Variants of the last one:
ping 1.1.1.1 -n 5 >nulIn this script there are some differences comparing it with the last one. This will not try to calllocalhost. Instead, it will try to connect to1.1.1.1, a very fast website. The action will last 5 secondsonly if you have an active internet connection. Else it will last approximately 15 to complete the action. I do not recommend using this method.
ping 127.0.0.1 -n 5 >nulThis is exactly the same as example 2 (most used). Also, you can also use:
ping [::1] -n 5 >nulThis instead, uses IPv6'slocalhost version.
There are lots of methods to perform this action. However, I prefer method 1 for Windows Vista and later versions and the most used method (method 2) for earlier versions of the OS.
Comments
The pathping.exe can sleep less than second.
@echo offsetlocal EnableDelayedExpansion echo !TIME! & pathping localhost -n -q 1 -p %~1 2>&1 > nul & echo !TIME!.
> sleep 1017:01:33,5717:01:33,60> sleep 2017:03:56,5417:03:56,58> sleep 5017:04:30,8017:04:30,87> sleep 10017:07:06,1217:07:06,25> sleep 20017:07:08,4217:07:08,64> sleep 50017:07:11,0517:07:11,57> sleep 80017:07:18,9817:07:19,81> sleep 100017:07:22,6117:07:23,62> sleep 150017:07:27,5517:07:29,06Comments
I am impressed with this one:
http://www.computerhope.com/batch.htm#02
choice /n /c y /d y /t 5 > NULTechnically, you're telling thechoice command to accept only y. It defaults to y, to do so in 5 seconds, to draw no prompt, and to dump anything it does say to NUL (like null terminal on Linux).
1 Comment
CHOICE versions I know, if someone hits a key while waiting, which impatient folks do sometimes, then choice will read an input, give a system beep for a bad input, and halt the countdown, so it will hang unless they push Y. And if they just happen to push Y, then the choice ends right there instead of waiting for 5. Also, this choice is using really weird Vista syntax. The normal choice commands instead useCHOICE /T:Y,5 > NUL for that. (There is no /D flag in the old versions.) And if you have Vista, useTIMEOUT instead.You can also use a .vbs file to do specific timeouts:
The code below creates the .vbs file. Put this near the top of you rbatch code:
echo WScript.sleep WScript.Arguments(0) >"%cd%\sleeper.vbs"The code below then opens the .vbs and specifies how long to wait for:
start /WAIT "" "%cd%\sleeper.vbs" "1000"In the above code, the "1000" is the value of time delay to be sent to the .vbs file in milliseconds, for example, 1000 ms = 1 s. You can alter this part to be however long you want.
The code below deletes the .vbs file after you are done with it. Put this at the end of your batch file:
del /f /q "%cd%\sleeper.vbs"And here is the code all together so it's easy to copy:
echo WScript.sleep WScript.Arguments(0) >"%cd%\sleeper.vbs"start /WAIT "" "%cd%\sleeper.vbs" "1000"del /f /q "%cd%\sleeper.vbs"Comments
Since others are suggesting 3rd party programs (Python, Perl, custom app, etc), another option is GNU CoreUtils for Windows available athttp://gnuwin32.sourceforge.net/packages/coreutils.htm.
2 options for deployment:
- Install full package (which will include the full suite of CoreUtils, dependencies, documentation, etc).
- Install only the 'sleep.exe' binary and necessary dependencies (use depends.exe to get dependencies).
One benefit of deploying CoreUtils is that you'll additionally get a host of other programs that are helpful for scripting (Windows batch leaves a lot to be desired).
Comments
Just for fun, if you have Node.js installed, you can use
node -e 'setTimeout(a => a, 5000)'to sleep for 5 seconds. It works on a Mac with Node v12.14.0.
1 Comment
await:node --input-type=module -e "await new Promise(resolve=>setTimeout(resolve, 5000))" (yes, the OP's is better, haha)There are many answers on this issue noting the use of ping, but most of them point to loopback addresses or addresses that are now seen as valid addresses for DNS.
Instead of that, you should use a TEST-NET IP address reserved for documentation use only, per the IETF.
(more information on that here)
Here is a fully commented batch script to demonstrate the use of a sleep function using ping:
@echo off:: turns off command-echoingecho/Script will now wait for 2.5 seconds & echo/:: prints a line followed by a linebreakcall:sleep 2500:: waits for two-and-a-half seconds (2500 milliseconds)echo/Done! Press any key to continue ... & pause >NUL:: prints a line and pausesgoto: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 = timeoutgoto:EOF:: ends the call subroutineAnd of course, you can also just use the command directly if you don't want to make a function:ping 203.0.113.0 -n 1 -wtimeInMilliseconds >NUL
Comments
You can get fancy by putting the PAUSE message in the title bar:
@ECHO offSET TITLETEXT=SleepTITLE %TITLETEXT%CALL :sleep 5GOTO :END:: Function Section:sleep ARGECHO 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:ENDpause::this is EOFComments
Explore related questions
See similar questions with these tags.


















