睡在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没有任何回应。 ;-)也许这不是很可能失败,但这不是不可能的…
如果你想确保你正在等待指定的时间,你应该使用sleep
function(这也有不使用CPU电源或等待networking准备就绪的优点)。
find一个已经做好的睡眠可执行文件是最方便的方法。 只要将其放入Windows文件夹或标准path的任何其他部分即可使用。
否则,如果你有一个编译环境,你可以很容易地自己做一个。 Sleep
function在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。
阅读更早的答案毫秒。