How to pause execution for a while in a Windows batch file between a command and the next one?
-
Is this intended to become a canonical? If so then some explanatory text might be appropriate. – John Gardeniers Sep 26 '12 at 23:06
-
2"Explanatory text" as in? – Massimo Sep 27 '12 at 07:00
-
2Most, if not all, canonical questions I've seen include text describing the intent of that question. – John Gardeniers Sep 27 '12 at 08:52
-
Or some text explaining the situation... It's mostly to help with SEO, but also helps to frame potential Answers. – Chris S Sep 28 '12 at 01:12
-
I actually thought about it, but this just seemed something too silly to be explicitly included in the Big List of Canonical Questions... http://meta.serverfault.com/questions/1986/what-are-the-canonical-answers-weve-discovered-over-the-years – Massimo Sep 28 '12 at 06:35
-
4SEO working just fine. First hit for me on Google search. – jbo5112 Oct 01 '15 at 22:44
5 Answers
The correct way to sleep in a batch file is to use the timeout
command, introduced in Windows 2000.
To wait somewhere between 29 and 30 seconds:
timeout /t 30
The timeout would get interrupted if the user hits any key; however, the command also accepts the optional switch /nobreak
, which effectively ignores anything the user may press, except an explicit CTRL-C
:
timeout /t 30 /nobreak
Additionally, if you don't want the command to print its countdown on the screen, you can redirect its output to NUL
:
timeout /t 30 /nobreak > NUL
-
6The timeout command does not work with Windows XP even with the 2003 Resource kit installed and the sleep command does not work in Windows 7 so the ping command can still be of good use if you are using the batch file on both Win7 and WinXP. – Jun 20 '13 at 22:55
-
21timeout does not work in non-interactive scripts: "ERROR: Input redirection is not supported, exiting the process immediately." so sometimes using hack with "ping" is preferred. – iMysak Oct 26 '15 at 11:08
-
2for the record, if the stdin is closed this command will exit immediately! – andras.tim Jan 23 '20 at 02:22
-
For the record, this works fine in Windows 10 2004 (b19041.630): C:\WINDOWS\system32>timeout /t 5 & ping mit.edu -- This pauses/counts down for 5 seconds, then pings mit.edu 4x and drops to the prompt just as expected. – Rook Aug 09 '21 at 12:53
-
In windows XP you can use `choice /t 10 /D N` when you copy the `choice.com` from your windows 98 into your windows xp. Unfortunally Windows XP has no native `timeout` or `choice` – Radon8472 Nov 08 '21 at 14:01
-
A stupid workaround for stdin closure: `ssh -t localhost timeout /t 30
– Simon Kissane May 06 '22 at 10:12
Since it applies here, too, I'll copy my answer from another site.
If you want to use ping, there is a better way. 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 is 192.0.2.x
. This is not made-up, it really is an address with the sole purpose of not-existing (it may not be clear, but it applies even in local networks):
192.0.2.0/24 - This block is assigned as "TEST-NET" for use in documentation and example code. It is often used in conjunction with domain names example.com or example.net in vendor and protocol documentation. Addresses within this block should not appear on the public Internet.
To sleep for 123 milliseconds, use ping 192.0.2.1 -n 1 -w 123 >nul
-
3Please don't do that, even if it's *slightly* better than pinging a real address. `Ping` is simply the *wrong* tool for the job. – Massimo Jul 17 '14 at 12:39
-
3@Massimo It's most likely not what it was intended to do :) But I think it's a good solution still - it does work better than timeout in some scenarios (in particular higher resolution). Also, it's become quite well known, so most people would not be very surprised (i.e. confused) when they see it in your batch file. – mafu Jul 18 '14 at 08:15
-
This QA was created *exactly* to point out the right solution to the problem, because there are several other similar questions which were answered with "just use ping" or similar kludges. – Massimo Jul 18 '14 at 11:15
-
2@Massimo Alright! I guess we just have different views. If you don't mind I'll still leave this answer up since it seems to be better than pinging localhost n times as is most often described. – mafu Jul 18 '14 at 11:25
-
9timeout is the right solution for the operating systems it works on. ping is the only solution that works from 5.1-6.3. With 25% of systems still on 5.1, timeout is not "the correct way". – Wyrmwood Jul 23 '14 at 01:42
-
4timeout is the wrong solution for any operating system, because it is fatally broken even in Windows 10. What use is a command that fails just because input is redirected? – Harry Johnston Apr 28 '19 at 00:22
-
2One reason to keep this up is that many people are using ping in scripts. Reading it, I was very confused why would one do that, but this answers shows why. – Davidmh Sep 06 '21 at 07:45
You can sleep in Batch using powershell:
Milliseconds
powershell -nop -c "& {sleep -m Milliseconds}"
Seconds
powershell -nop -c "& {sleep seconds}"
- 281
- 2
- 8
-
2
-
2Yes, this works much better than 'timeout' Example: powershell -nop -c "& {sleep 10}" – ZaSter Apr 21 '21 at 15:48
-
1This solution has worked for me in Win10, in an unattended .bat script. – Cirieno Apr 26 '21 at 15:06
-
1Wish I could upvote this answer a few more times. Worked perfectly in my unattended script. – BWhite Sep 15 '21 at 16:13
You can also insert a ping
to localhost. This will take 4 seconds to complete (by default). It is considered a kludge by some, but works quite well all the same.
The command:
ping 127.0.0.1
-
6Ehm... the whole purpose of this Q/A was *exactly* to correct two other questions which have this as their accepted answer, but can no longer be corrected because their OP is no longer around. – Massimo Sep 26 '12 at 20:13
-
6While it will work it's the equivalent of driving a screw with a hammer. A wrong tool may work, but it's still wrong. – voretaq7 Sep 26 '12 at 20:16
-
1
-
1@MarkAllen This is indeed true, but it's also the reason people are still using this kludge even when better and more suited tools have been available for a while (and let's not even get into talk about who uses a `choice` with a timeout). A little bit of reasearch into using *proper* tools for the job should be the duty of any computing professional (or any professional *at all*). – Massimo Sep 27 '12 at 07:03
-
5@MarkAllen - technically you then have to worry about whether or not `ping` comes with your OS. If you're worried enough about '95 '98 or ME then you should be as equally worried about 6.22 which doesn't have `ping` either – Mark Henderson Sep 27 '12 at 20:36
-
2@Massimo Call it baby duck syndrome. Oh - I just saw your comment above. You weren't even asking this as a real question, you just wanted your answer to be the answer to the question in general. I see. Maybe next time you could include that in your question. Then I could have wasted zero time on it. – Mark Allen Sep 28 '12 at 00:00
-
4@MarkHenderson It's easier (for me) to remember whether or not a particular release of the OS supports TCP/IP than to remember whether or not it includes a command I hadn't heard previously. You know? – Mark Allen Sep 28 '12 at 00:01
-
Doing a `postSync` command with `MsDeploy.exe`, neither `Sleep` or `Timeout` seemed to work properly. This was the only one that would actually cause a delay. Hacky, but thanks! – deadlydog Oct 26 '18 at 22:02
-
Since `timeout` is fatally broken (see comments to the accepted answer) this is a better solution. – Harry Johnston Apr 28 '19 at 00:20
Disclaimer: this is not the "ideal" solution, so don't bother beating me over the head with that like done to those recommending ping
...
When possible, use timeout
for sure. But as noted in the comments, that's not always an option (e.g. in non-interactive mode). After that, I agree that the ping
"kludge" is perhaps the next best option, as it is very simple. That said, I offer another option... embed some VB Script.
The basis of this solution has all sorts of application beyond this. Often VBS can do things that batch cannot, or at the very least do so with drastically more ease. Using the technique illustrated here, you can mix the two (not "seamlessly", but "functionally"...).
Here's a one liner, to create a temp script, execute it, then delete it. The script does the sleeping for you (for 3 seconds in this example).
echo WScript.Sleep 3000 > %temp%\sleep.vbs & cscript %temp%\sleep.vbs %sleepMs% //B & del %temp%\sleep.vbs
Here's basically the same thing, written a bit differently:
set sleepMs=3000 & set sleepVbs=%temp%\sleep.vbs & echo WScript.Sleep WScript.Arguments(0) > %sleepVbs% & cscript %sleepVbs% %sleepMs% //B & del %sleepVbs%
And then finally, like ping
, CScript
itself has a timeout option! So, if you enter an infinite loop in the script, you can let the interpreter enforce the duration. Note, this is a "busy" operation, which eats the CPU, and therefore I don't recommend it when you can use the WScript.Sleep
procedure, but I present it as a conceptual option for the sake of completeness:
set sleepSec=3 & set sleepVbs=%temp%\sleep.vbs & echo While True > %sleepVbs% & echo Wend >> %sleepVbs% & cscript %sleepVbs% //B //T:%sleepSec% & del %sleepVbs%
- 399
- 3
- 11
-
You know ... you could do this in powershell, I expect, without having to write a file. – Harry Johnston Apr 28 '19 at 00:20
-
Yeah, that is likely another good solution, though this one I believe is more backwards compatible with old versions of Windows. – BuvinJ Apr 28 '19 at 01:03