睡在batch file中

当编写一个batch file在Windows上自动化某些东西时,我需要暂停执行几秒钟(通常在一个testing/等待循环中,等待一个进程启动)。 当时,我能find的最好的解决scheme使用ping(我不要你)来达到预期的效果。 我在这里发现了一个更好的写法,它描述了一个可调用的“wait.bat”,实现如下:

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

然后,您可以在自己的batch file中包含对wait.bat的调用,传入睡眠秒数。

显然,Windows 2003资源工具包提供了类似Unix的睡眠命令 (最后!)。 与此同时,对于我们这些仍在使用Windows XP,Windows 2000或(可惜) Windows NT的人来说 ,还有更好的方法吗?

我在接受的答案中修改了sleep.py脚本,如果在命令行中没有parameter passing,它将默认为一秒。

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

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

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

如果你有这样的需求,它将允许秒暂停(例如,1.5秒,0.1等)。 如果你想把它叫做sleep而不是sleep.py ,那么你可以将.PY扩展名添加到你的PATHEXT环境variables中。 在Windows XP上,您可以在以下位置进行编辑:

我的电脑→属性(菜单)→高级(选项卡)→环境variables(button)→系统variables(帧)

从Windows Vista开始,可以使用timeout命令:

 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 

注意:它不适用于inputredirect – 简单的例子:

 C:\>echo 1 | timeout /t 1 /nobreak ERROR: Input redirection is not supported, exiting the process immediately. 

如上所述,使用ping方法是我无法(或不想)添加更多可执行文件或安装任何其他软件时的操作方法。

你应该ping那些不在那里的东西,然后使用-w标志,以便在这段时间之后失败,而不是ping那些那里的东西(比如localhost) -n次。 这可以让你处理时间less于一秒钟,我认为它稍微更准确。

例如

(testing1.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 

我不同意我在这里find的答案。

我使用完全基于Windows XPfunction的以下方法在batch file中执行延迟:

DELAY.BAT:

 @ECHO OFF REM DELAY seconds REM GET ENDING SECOND FOR /F "TOKENS=1-3 DELIMS=:." %%A IN ("%TIME%") DO SET /AH=%%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 /AH=%%A, M=1%%B%%100, S=1%%C%%100, CURRENT=(H*60+M)*60+S IF %CURRENT% LSS %ENDING% GOTO WAIT 

您也可以在计算中插入一天,以便在延迟时间间隔午夜过后,该方法也可以工作。

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

 Usage: sleep time-to-sleep-in-seconds sleep [-m] time-to-sleep-in-milliseconds sleep [-c] commited-memory ratio (1%-100%) 

我遇到了类似的问题,但我只是敲了一个很短的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; } 

在Server Fault上, 有人问到类似的问题 ,解决scheme是:

 choice /dy /t 5 > nul 

你可以使用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"); 

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

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

例如等待5秒钟,使用

 ping -n 6 localhost >nul 2>&1 

或者在Windows 7或更高版本中使用timeout

 timeout 6 >nul 

你可以使用ping:

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

它将等待10秒钟。

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

请记住, -w的目的不是等待一秒钟。 这是为了确保在出现networking问题时等待不到一秒钟。 ping自己会每秒发送一个ICMP数据包。 这可能不是本地主机所必需的,但是老习惯很难消除。

把它放在你想要等待的batch file中。

 @ping 127.0.0.1 -n 11 -w 1000 > null 

在记事本中,写下:

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

只是使用

超时/吨

例如,我主要用它作为

超时/ t 2 / nobreak> NUL

这意味着该脚本将继续等待2秒钟。 默认情况下,按键会立即将超时设置为0,所以在后面加上“/ nobreak”,这样就不能停止超时。 此外,> NUL使超时隐形,因为它通常说明要走多less秒。

如果你的系统上有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比你的睡眠时间开始花费更less的时间,这种方法将工作(这是我的机器上大约600毫秒)。

资源工具包一直包括这个。 至less从Windows 2000开始。

另外,Cygwin软件包还有一个sleep ,将其放入PATH中,并包含cygwin.dll (或其他所谓的程序)和path!

我喜欢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 /AH=%%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 /AH=%%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 

我一直在使用这个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"); } } } } 

有一个更好的方式来睡觉使用ping。 你会想ping一个不存在的地址,所以你可以指定一个毫秒级的超时精度。 幸运的是,这样的地址是在一个标准(RFC 3330)中定义的,它是192.0.2.x 这不是化妆,它确实是一个地址的唯一目的不存在(可能不清楚,但它适用于本地networking):

192.0.2.0/24 – 该块被指定为“TEST-NET”,用于文档和示例代码。 它通常与供应商和协议文档中的域名example.com或example.net一起使用。 此块内的地址不应出现在公共Internet上。

睡123毫秒,使用ping 192.0.2.1 -n 1 -w 123 >nul

ping的用法很好,只要你想“等一下”。 这是因为你依赖于下面的其他function,比如你的networking工作和127.0.0.1没有任何回应。 ;-)也许这不是很可能失败,但这不是不可能的…

如果你想确保你正在等待指定的时间,你应该使用sleepfunction(这也有不使用CPU电源或等待networking准备就绪的优点)。

find一个已经做好的睡眠可执行文件是最方便的方法。 只要将其放入Windows文件夹或标准path的任何其他部分即可使用。

否则,如果你有一个编译环境,你可以很容易地自己做一个。 Sleepfunction在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); 

您将在睡眠function (MSDN)中find有关此function(Windows 2000以后可用)的更多信息。

在标准C中, sleep()包含在标准库中,而在Microsoft的Visual Studio C中,函数名为Sleep() ,如果内存为我服务的话。 ;-)这两个参数在几秒钟内,而不是以前两个声明的毫秒数。

比Python解决scheme更轻量级的是Perl一行。

睡七秒钟把这个放在BAT脚本中:

 perl -e "sleep 7" 

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

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

我已经使用ActivePerl多年。 这是很容易安装。

在Windows 2000之后的所有Windows版本上运行的最佳解决scheme是:

 timeout numbersofseconds /nobreak > nul 

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

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

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 

我对这个印象深刻:

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

 choice /n /cy /dy /t 5 > NUL 

从技术上讲,你只是告诉choice命令只接受y。 它默认为y,在5秒钟内完成,不提示任何提示,并转储它对NUL所说的任何内容(如Linux上的nullterminal)。

在Windows Vista上,您有TIMEOUT和SLEEP命令,但要在Windows XP或Windows Server 2003上使用它们,则需要Windows Server 2003资源工具包 。

在这里,您可以很好地了解睡眠select(ping方法是最stream行的,因为它可以在每台Windows机器上运行),但是(至less)没有提到哪个(ab)使用W32TM (时间服务)命令:

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

在哪里你应该用你想暂停的秒数replaceN. 此外,它将在没有先决条件的每个Windows系统上工作。

Typeperf也可以使用:

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

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

下面的代码创build.vbs文件。 把这个靠近你的顶部rbatch代码:

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

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

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

在上面的代码中,“1000”是以毫秒为单位发送到.vbs文件的时间延迟值,例如1000ms = 1s。 你可以改变这个部分,但不pipe你想要的长。

完成后,下面的代码将删除.vbs文件。 把它放在你的batch file的末尾:

 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" 

您可以通过在标题栏中放置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 

这已在Windows XP SP3和Windows 7上进行了testing,并使用CScript。 我join了一些安全警卫,以避免提示。 ( /q会很危险)

等一秒钟

sleepOrDelayExecution 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 
 ping -n X 127.0.0.1 > nul 

用秒数+ 1replaceX.

例如,如果您要等待10秒钟,请将Xreplace为11.要等待5秒钟,请使用6。

阅读更早的答案毫秒。