158

在编写批处理文件以在 Windows 机器上自动执行某些操作时,我需要暂停其执行几秒钟(通常在测试/等待循环中,等待进程启动)。当时,我能找到的最佳解决方案是使用 ping (我不骗你)来达到预期的效果。我在这里找到了一个更好的文章,它描述了一个可调用的“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 Resource Kit 提供了一个类似 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)
4

32 回答 32

236

timeout命令从 Windows Vista 开始可用:

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 -1

注意:它不适用于输入重定向 - 简单的示例:

C:\>echo 1 | timeout /t 1 /nobreak
ERROR: Input redirection is not supported, exiting the process immediately.
于 2011-03-30T08:38:43.610 回答
21

ping当我不能(或不想)添加更多可执行文件或安装任何其他软件时,使用概述的方法是我的做法。

您应该 ping 不存在的东西,并使用-w标志使其在这段时间后失败,而不是 ping 存在的东西如本地主机)-n次。这使您可以处理不到一秒的时间,而且我认为它稍微准确一些。

例如

(测试没有采取 1.1.1.1)

ECHO Waiting 15 seconds

PING 1.1.1.1 -n 1 -w 15000 > NUL
  or
PING -n 15 -w 1000 127.1 >NUL
于 2011-07-28T00:20:12.243 回答
18

更新

从 Windows Vista 及更高版本可用的命令应该是使用的timeout命令,如该问题的另一个答案中所述。下面是一个答案。

旧答案

如果您安装了 Python,或者不介意安装它(它也有其他用途:),只需创建以下sleep.py脚本并将其添加到 PATH 中的某个位置:

import time, sys

time.sleep(float(sys.argv[1]))

如果您有这样的需要,它将允许亚秒级的暂停(例如,1.5 秒、0.1 秒等)。如果您想将其称为sleep而不是sleep.py,则可以将.PY扩展名添加到 PATHEXT 环境变量中。在 Windows XP 上,您可以在以下位置进行编辑:

我的电脑→属性(菜单)→高级(选项卡)→环境变量(按钮)→系统变量(框架)

于 2008-10-03T10:42:19.897 回答
16

SLEEP.exe包含在大多数资源工具包中,例如Windows Server 2003 资源工具包,它也可以安装在 Windows XP 上。

Usage:  sleep      time-to-sleep-in-seconds
        sleep [-m] time-to-sleep-in-milliseconds
        sleep [-c] commited-memory ratio (1%-100%)
于 2008-10-03T09:15:39.260 回答
15

我不同意我在这里找到的答案。

我完全基于 Windows XP 功能使用以下方法对批处理文件进行延迟:

延迟.BAT:

@ECHO OFF
REM DELAY seconds

REM GET ENDING SECOND
FOR /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+%1

REM WAIT FOR SUCH A SECOND
:WAIT
FOR /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+S
IF %CURRENT% LSS %ENDING% GOTO WAIT

您还可以在计算中插入日期,以便在延迟间隔超过午夜时该方法也有效。

于 2011-07-24T10:10:43.117 回答
13

我遇到了类似的问题,但我只是敲开了一个非常短的 C++ 控制台应用程序来做同样的事情。只需运行MySleep.exe 1000 - 可能比下载/安装整个资源包更容易。

#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;
}
于 2008-10-03T09:35:43.543 回答
10

您可以使用 ping:

ping 127.0.0.1 -n 11 -w 1000 >nul: 2>nul:

它将等待 10 秒。

您必须使用 11 的原因是因为第一个 ping 会立即消失,而不是在一秒钟后。该数字应始终比您要等待的秒数多一。

请记住,目的-w不是控制发送数据包的频率,而是确保在出现网络问题时等待不超过一段时间。如果您 p​​ing 127.0.0.1 不太可能有问题,所以这可能没有实际意义。

ping命令本身通常会每秒发送一个数据包。这实际上并没有记录在 Windows 文档中,但它似乎遵循与 Linux 版本相同的规则(记录在哪里)。

于 2009-08-20T08:28:55.757 回答
10

在 Server Fault 上,有人问了一个类似的问题,解决方案是:

choice /d y /t 5 > nul
于 2009-11-28T01:29:47.380 回答
9

您可以使用 Windows cscript WSH层和这个wait.js JavaScript 文件:

if (WScript.Arguments.Count() == 1)
    WScript.Sleep(WScript.Arguments(0)*1000);
else
    WScript.Echo("Usage: cscript wait.js seconds");
于 2009-11-28T02:00:40.420 回答
8

根据您的兼容性需求,可以使用ping

ping -n <numberofseconds+1> localhost >nul 2>&1

例如等待 5 秒,使用

ping -n 6 localhost >nul 2>&1

或在 Windows 7 或更高版本上使用timeout

timeout 6 >nul
于 2011-03-25T21:04:54.050 回答
8

使用 ping 有更好的睡眠方式。您需要 ping 一个不存在的地址,因此您可以指定毫秒精度的超时。幸运的是,这样的地址是在标准 (RFC 3330) 中定义的,它是192.0.2.x. 这不是虚构的,它确实是一个不存在的唯一目的的地址。需要明确的是,这甚至适用于本地网络。

192.0.2.0/24 - 此块被分配为“TEST-NET”,用于文档和示例代码。在供应商和协议文档中,它通常与域名 example.com 或 example.net 结合使用。此块内的地址不应出现在公共互联网上。

要休眠 123 毫秒,请使用ping 192.0.2.1 -n 1 -w 123 >nul

更新:根据评论,还有127.255.255.255.

于 2014-02-21T17:24:23.267 回答
7

如果您的系统上有PowerShell,则只需执行以下命令:

powershell -command "Start-Sleep -s 1"

编辑:从我对类似线程的回答中,人们提出了一个问题,即与您尝试等待的时间相比,powershell 启动所需的时间很重要。如果等待时间的准确性很重要(即不能接受一两秒的额外延迟),您可以使用这种方法:

powershell -command "$sleepUntil = [DateTime]::Parse('%date% %time%').AddSeconds(5); $sleepDuration = $sleepUntil.Subtract((get-date)).TotalMilliseconds; start-sleep -m $sleepDuration"

这需要发出 windows 命令的时间,并且 powershell 脚本会休眠到该时间后的 5 秒。因此,只要 powershell 的启动时间少于您的睡眠持续时间,这种方法就可以工作(在我的机器上大约需要 600 毫秒)。

于 2013-05-29T00:03:40.610 回答
7
timeout /t <seconds> <options>

例如,要让脚本执行不可中断的 2 秒等待:

timeout /t 2 /nobreak >NUL

这意味着脚本将在继续之前等待 2 秒。

默认情况下,击键会中断超时,因此/nobreak如果您不希望用户能够中断(取消)等待,请使用该开关。此外,超时将提供每秒通知,以通知用户还需要等待多长时间;这可以通过将命令传递到NUL.

编辑:正如@martineau 在评论中指出的那样,该timeout命令仅适用于 Windows 7 及更高版本。此外,该ping命令使用的处理器时间比timeout. 不过,我仍然相信timeout尽可能使用,因为它比ping“hack”更具可读性。在这里阅读更多。

于 2014-06-03T18:55:46.113 回答
5

只需将其放在您想要等待的批处理文件中。

@ping 127.0.0.1 -n 11 -w 1000 > null
于 2011-03-25T19:35:09.460 回答
4

资源工具包一直包含此内容。至少从 Windows 2000 开始。

此外,Cygwin 软件包有一个sleep- plop 将其放入您的 PATH 并包括cygwin.dll(或任何它的名称)和要走的路!

于 2008-10-03T09:13:05.803 回答
4

在记事本中,写:

@echo off
set /a WAITTIME=%1+1
PING 127.0.0.1 -n %WAITTIME% > nul
goto:eof

现在在文件夹 C:\WINDOWS\System32 中另存为 wait.bat,然后当你想等待时,使用:

CALL WAIT.bat <whole number of seconds without quotes>
于 2013-01-18T17:35:21.017 回答
3

ping的用法很好,只要你只是想“稍等一下”。这是因为您依赖于下面的其他功能,例如您的网络工作以及在 127.0.0.1 上没有任何响应的事实。;-) 也许它不太可能失败,但也不是不可能......

如果您想确保您正在等待指定的时间,您应该使用该sleep功能(它还有一个优点是它不使用 CPU 电源或等待网络准备好)。

找到一个已经生成的可执行文件用于睡眠是最方便的方法。只需将其放入您的 Windows 文件夹或标准路径的任何其他部分,它就始终可用。

否则,如果您有一个编译环境,您可以轻松地自己制作一个。该Sleep功能在 中可用kernel32.dll,因此您只需要使用该功能即可。:-) 对于 VB / VBA,在源代码的开头声明以下内容以声明睡眠功能:

private Declare Sub Sleep Lib "kernel32" Alias "Sleep" (byval dwMilliseconds as Long)

对于 C#:

[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);

您可以在睡眠功能(MSDN) 中找到有关此功能(自 Windows 2000 起可用)的更多信息。

在标准 C 中,sleep()包含在标准库中,在 Microsoft 的 Visual Studio C 中,函数名为Sleep(),如果我没记错的话。;-) 这两个参数以秒为单位,而不是像前两个声明那样以毫秒为单位。

于 2008-10-03T10:08:15.957 回答
3

我一直在使用这个 C# 睡眠程序。如果 C# 是您的首选语言,对您来说可能会更方便:

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");
            }
        }
    }
}
于 2009-07-07T14:39:09.053 回答
3

比 Python 解决方案更轻量级的是 Perl 单行。

要休眠 7 秒,请将其放入 BAT 脚本中:

perl -e "sleep 7"

该解决方案仅提供一秒的分辨率。

如果您需要更高的分辨率,请使用 CPAN 的 Time::HiRes 模块。它提供了usleep()哪些以微秒为单位休眠,nanosleep()哪些以纳秒为单位休眠(这两个函数都只接受整数参数)。请参阅堆栈溢出问题如何在 Perl 中休眠一毫秒?了解更多详情。

我已经使用ActivePerl很多年了。它很容易安装。

于 2009-07-29T18:12:24.757 回答
3

我喜欢Aacini 的回应。我添加到它来处理这一天,还使它能够处理厘秒%TIME%输出H:MM:SS.CC):

:delay
SET DELAYINPUT=%1
SET /A DAYS=DELAYINPUT/8640000
SET /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+DELAYINPUT
SET /A DAYS=DAYS+ENDING/8640000
SET /A ENDING=ENDING-(DAYS*864000)

::Wait for such a centisecond
:delay_wait
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, CURRENT=((H*60+M)*60+S)*100+X
IF DEFINED LASTCURRENT IF %CURRENT% LSS %LASTCURRENT% SET /A DAYS=DAYS-1
SET LASTCURRENT=%CURRENT%
IF %CURRENT% LSS %ENDING% GOTO delay_wait
IF %DAYS% GTR 0 GOTO delay_wait
GOTO :EOF
于 2013-01-29T02:30:37.333 回答
2

或命令行 Python,例如 6 秒半:

python -c "import time;time.sleep(6.5)"
于 2012-01-08T05:39:12.237 回答
2

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

timeout numbersofseconds /nobreak > nul
于 2014-02-05T19:30:27.417 回答
2

有很多方法可以在 cmd/batch中完成“睡眠”:

我最喜欢的一个:

TIMEOUT /NOBREAK 5 >NUL 2>NUL

这将使控制台停止 5 秒钟,没有任何输出。

最常被使用:

ping localhost -n 5 >NUL 2>NUL

这将尝试建立localhost5 次连接。由于它托管在您的计算机上,因此它将始终到达主机,因此每秒它都会尝试新的每秒。该-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 的localhost版本。

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

于 2020-06-23T00:47:06.710 回答
1

我对这个印象深刻:

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

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

从技术上讲,您是在告诉choice命令只接受 y。它默认为 y,在 5 秒内完成,不绘制任何提示,并将它所说的任何内容转储到 NUL(如 Linux 上的空终端)。

于 2011-04-28T17:15:08.887 回答
1

您还可以使用 .vbs 文件来执行特定的超时:

下面的代码创建 .vbs 文件。把它放在你的 rbatch 代码的顶部附近:

echo WScript.sleep WScript.Arguments(0) >"%cd%\sleeper.vbs"

下面的代码然后打开 .vbs 并指定等待多长时间:

start /WAIT "" "%cd%\sleeper.vbs" "1000"

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

完成后,下面的代码将删除 .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"
于 2014-01-21T08:28:47.237 回答
1

pathping.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
于 2017-02-01T14:09:37.267 回答
1

只是为了好玩,如果你安装了 Node.js,你可以使用

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

睡5秒。它适用于带有 Node v12.14.0 的 Mac。

于 2019-12-28T14:56:05.343 回答
0

您可以通过将 PAUSE 消息放在标题栏中来获得幻想:

@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
于 2013-09-05T19:58:32.283 回答
0

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

在这里,您对睡眠替代方案有一个很好的概述(ping 方法是最流行的,因为它适用于每台 Windows 机器),但是(至少)有一个没有提到(ab)使用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);
}
于 2014-01-08T11:50:43.363 回答
0

这在 Windows XP SP3 和 Windows 7 上进行了测试,并使用 CScript。我放置了一些安全卫士以避免 del "" 提示。(/q会很危险)

等待一秒钟:

睡眠或延迟执行 1000

等待 500 毫秒,然后运行以下内容:

sleepOrDelayExecution 500 dir \ /s

sleepOrDelayExecution.bat:

@echo off
if "%1" == "" goto end
if NOT %1 GTR 0 goto end
setlocal
set sleepfn="%temp%\sleep%random%.vbs"
echo WScript.Sleep(%1) >%sleepfn%
if NOT %sleepfn% == "" if NOT EXIST %sleepfn% goto end
cscript %sleepfn% >nul
if NOT %sleepfn% == "" if EXIST %sleepfn% del %sleepfn%
for /f "usebackq tokens=1*" %%i in (`echo %*`) DO @ set params=%%j
%params%
:end
于 2014-01-29T14:01:10.200 回答
0

由于其他人建议使用 3rd 方程序(Python、Perl、自定义应用程序等),另一种选择是适用于 Windows 的 GNU CoreUtils,可在http://gnuwin32.sourceforge.net/packages/coreutils.htm获得。

2个部署选项:

  1. 安装完整的软件包(其中将包括全套 CoreUtils、依赖项、文档等)。
  2. 仅安装“sleep.exe”二进制文件和必要的依赖项(使用depends.exe 获取依赖项)。

部署 CoreUtils 的一个好处是,您还将获得许多其他有助于脚本编写的程序(Windows 批处理还有很多不足之处)。

于 2018-11-13T01:23:20.090 回答
-2
ping -n X 127.0.0.1 > nul

将 X 替换为秒数 + 1。

例如,如果您要等待 10 秒,请将 X 替换为 11。要等待 5 秒,请使用 6。

阅读较早的答案几毫秒。

于 2014-07-28T07:51:43.573 回答