[python] 睡在一个批处理文件中



13 Answers

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.
Question

当编写一个批处理文件来自动化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资源工具包提供了类似Unix的睡眠命令 (最后!)。 同时,对于我们这些仍在使用Windows XP,Windows 2000或(可惜) Windows NT的用户来说 ,还有更好的方法吗?

我在接受的答案中修改了sleep.py脚本,以便在命令行上没有参数传递时默认为1秒。

import time, sys

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



我对这个印象深刻:

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

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

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




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

睡七秒钟,把它放在BAT脚本中:

perl -e "sleep 7"

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

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

我已经使用ActivePerl很多年了。 安装非常简单。




在记事本中,写下:

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



这已在Windows XP SP3和Windows 7上测试过,并使用CScript。 我加入了一些安全警卫以避免提示。 ( /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



timeout /t <seconds> <options>

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

timeout /t 2 /nobreak >NUL

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

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

编辑:正如martineau 在评论中指出的那样timeout命令仅在Windows 7及更高版本上可用。 此外, ping命令使用的处理器时间少于timeout 。 尽管如此,我仍然相信尽可能使用timeout ,因为它比ping'hack'更具可读性。 here阅读更多。




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

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

DELAY.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

您也可以在计算中插入一天,以便在延迟时间间隔经过午夜时方法也可以使用。




你可以使用ping:

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

它将等待10秒钟。

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

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




您也可以使用.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"



我面临类似的问题,但我只是敲了一个非常短的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;
}



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



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




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



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

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



Related