Спящий в пакетном файле

135 Jason Etheridge [2008-10-03 12:10:00]

При написании пакетного файла для автоматизации чего-либо в окне 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 script в принятом ответе, так что он по умолчанию занимает одну секунду, если в командной строке не передаются аргументы:

import time, sys

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

python batch-file


29 ответов


15 Решение tzot [2008-10-03 13:42:00]

Если у вас установлен Python или не против его установки (у него тоже есть другие возможности:), просто создайте следующий sleep.py script и добавьте его где-нибудь в свой PATH:

import time, sys

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

Это позволит использовать субсекундные паузы (например, 1,5 с, 0,1 и т.д.), если у вас есть такая необходимость. Если вы хотите называть это как sleep, а не sleep.py, вы можете добавить расширение .PY в переменную среды PATHEXT. В Windows XP можно изменить его в:

Мой компьютер → Свойства (меню) → Дополнительно (вкладка) → Переменные среды (кнопка) → Системные переменные (кадр)


201 Blorgbeard [2011-03-30 11:38:00]

Команда 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.

21 daniel [2011-07-28 03:20:00]

Используя метод ping, как описано, как это сделать, когда я не могу (или не хочу) добавлять дополнительные исполняемые файлы или устанавливать любое другое программное обеспечение.

Вы должны пинговать что-то, чего там нет, и использовать флаг -w, чтобы он терпел неудачу после такого количества времени, а не пинговать что-то, что есть (например, localhost) -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

15 Luk [2008-10-03 12:15:00]

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%)

15 Aacini [2011-07-24 13:10:00]

Я не согласен с ответами, которые я нашел здесь.

Я использую следующий метод, полностью основанный на возможностях 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

Вы также можете вставить день в вычисление, чтобы этот метод также работал, когда интервал задержки прошел за полночь.


13 John Sibly [2008-10-03 12:35:00]

У меня возникла аналогичная проблема, но я просто сбил очень короткое консольное приложение на С++, чтобы сделать то же самое. Просто запустите 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;
}

10 mlsteeves [2009-11-28 04:29:00]

Сбой при Server Fault, был задан аналогичный вопрос, было решение:

choice /d y /t 5 > nul

9 Blake7 [2009-11-28 05:00:00]

Вы можете использовать Windows cscript WSH и этот файл JavaScript wait.js:

if (WScript.Arguments.Count() == 1)
    WScript.Sleep(WScript.Arguments(0)*1000);
else
    WScript.Echo("Usage: cscript wait.js seconds");

8 Joey [2011-03-26 00:04:00]

В зависимости от ваших потребностей в совместимости используйте ping:

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

например. подождите 5 секунд, используйте

ping -n 6 localhost >nul 2>&1

или в Windows 7 или более поздней версии используйте timeout:

timeout 6 >nul

7 paxdiablo [2009-08-20 11:28:00]

Вы можете использовать ping:

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

Он будет ждать 10 секунд.

Причина, по которой вы должны использовать 11, состоит в том, что первый пинг выходит сразу, а не через одну секунду. Номер всегда должен быть больше, чем количество секунд, которое вы хотите подождать.

Имейте в виду, что цель -w - не ждать одной секунды. Это позволит вам ждать не более одной секунды, если есть проблемы с сетью. ping сам пошлет один ICMP-пакет в секунду. Вероятно, это не требуется для локального хоста, но старые привычки умирают.


5 Brent Stewart [2011-03-25 22:35:00]

Просто поместите это в свой командный файл, где вы хотите подождать.

@ping 127.0.0.1 -n 11 -w 1000 > null

4 Daren Thomas [2008-10-03 12:13:00]

Resource Kit всегда включал это. По крайней мере, с Windows 2000.

Кроме того, пакет Cygwin имеет sleep - plop, который находится в вашем PATH, и включает в себя cygwin.dll (или что бы он там ни называл) и путь!


4 SuperKael [2013-01-18 20:35:00]

В Блокноте напишите:

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

Теперь сохраните как wait.bat в папке C:\WINDOWS\System32, то всякий раз, когда вы хотите подождать, используйте:

CALL WAIT.bat <whole number of seconds without quotes>

4 Niall Connaughton [2013-05-29 03:03:00]

Если у вас есть PowerShell в вашей системе, вы можете просто выполнить эту команду:

powershell -command "Start-Sleep -s 1"

Изменить: от мой ответ на аналогичный поток, люди подняли проблему, когда количество времени, которое требуется для запуска, будет значительным по сравнению с тем, как долго вы пытаетесь ждать. Если важна точность времени ожидания (т.е. Вторая или две дополнительные задержки неприемлемы), вы можете использовать этот подход:

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

Это занимает время, когда была выписана команда Windows, а powershell script спящий до 5 секунд после этого времени. Таким образом, пока PowerShell занимает меньше времени, чем ваша продолжительность сна, этот подход будет работать (он составляет около 600 мс на моей машине).


4 mgthomas99 [2014-06-03 21:55:00]

timeout /t <seconds> <options>

Например, чтобы сделать script выполнение не-прерывистого 2-секундного ожидания:

timeout /t 2 /nobreak >NUL

Это означает, что script будет ждать 2 секунды, прежде чем продолжить.

По умолчанию нажатие клавиши прерывает таймаут, поэтому используйте переключатель /nobreak, если вы не хотите, чтобы пользователь мог прервать (отменить) ожидание. Кроме того, тайм-аут будет предоставлять уведомления за секунду, чтобы уведомить пользователя о том, как долго осталось ждать; это можно удалить, выполнив команду NUL.

изменить. @martineau указывает в комментариях, Команда timeout доступна только для Windows 7 и выше. Кроме того, команда ping использует меньшее процессорное время, чем timeout. Я по-прежнему верю в использование timeout, где это возможно, хотя это более читаемо, чем ping 'hack'. Подробнее здесь.


3 Hossy [2013-01-29 05:30:00]

Мне нравится ответ Aacini. Я добавил к нему, чтобы обработать этот день, а также позволить ему обрабатывать centiseconds (%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

3 mafu [2014-02-21 20:24:00]

Есть лучший способ спать, используя пинг. Вы захотите выполнить 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


3 Liam [2009-07-07 17:39:00]

Я использую эту программу сна С#. Это может быть более удобно для вас, если С# - ваш предпочтительный язык:

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");
            }
        }
    }
}

2 Tato [2014-02-05 22:30:00]

Лучшим решением, которое должно работать на всех версиях Windows после Windows 2000, будет следующее:

timeout numbersofseconds /nobreak > nul

2 Tooony [2008-10-03 13:08:00]

Использование ping является хорошим, если вы просто хотите "подождать немного". Это связано с тем, что вы зависите от других функций, таких как ваша сеть, и того факта, что на 127.0.0.1 ничего не найдено.;-) Возможно, это маловероятно, но это не невозможно...

Если вы хотите быть уверенным, что вы ожидаете точно указанное время, вы должны использовать функциональность sleep (которая также имеет то преимущество, что она не использует мощность процессора или не ждет, когда сеть станет готовой).

Найти уже сделанный исполняемый файл для сна - самый удобный способ. Просто запустите его в свою папку Windows или любую другую часть вашего стандартного пути, и она всегда доступна.

В противном случае, если у вас есть среда компиляции, вы можете легко сделать ее самостоятельно. Функция sleep доступна в kernel32.dll, поэтому вам просто нужно использовать ее.:-) Для VB/VBA объявите следующее в начале вашего источника, чтобы объявить функцию сна:

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

Для С#:

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

Подробнее об этой функциональности (доступной с Windows 2000) вы найдете в функция сна (MSDN).

В стандарте C, sleep() включен в стандартную библиотеку, а в Microsoft Visual Studio C функция называется sleep(), если мне служит память.;-) Эти два аргумента принимают за секунды, а не в миллисекундах, как две предыдущие объявления.


2 Peter Mortensen [2009-07-29 21:12:00]

Еще более легкий, чем решение Python, - это Perl один вкладыш.

Чтобы спать в течение семи секунд, поместите это в BAT script:

perl -e "sleep 7"

Это решение обеспечивает разрешение одной секунды.

Если вам требуется более высокое разрешение, используйте Time:: HiRes модуль из CPAN. Он обеспечивает usleep(), который спит в микросекунд и nanosleep(), который спит в наносекундах (обе функции принимают только целые аргументы). См. Stack Вопрос о переполнении Как спятиться за миллисекунду в Perl? для получения дополнительной информации.

Я использовал ActivePerl в течение многих лет. Очень легко установить.


1 Andry [2017-02-01 17:09:00]

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

1 EpicNinjaCheese [2014-01-21 11:28:00]

Вы также можете использовать файл .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"

1 Alex Robinson [2012-01-08 08:39:00]

Или в командной строке Python, например, в течение 6 с половиной секунд:

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

1 Chris Moschini [2011-04-28 20:15:00]

Я впечатлен этим:

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

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

Технически вы сообщаете команде choice принимать только y. По умолчанию он равен y, чтобы сделать это за 5 секунд, чтобы не нарисовать приглашение, и сбросить все, что он говорит в NUL (например, нулевой терминал в Linux).


1 npocmaka [2014-01-08 14:50:00]

Из Windows Vista у вас есть TIMEOUT и SLEEP, но для их использования в Windows XP или Windows Server 2003 вам понадобится набор инструментов для Windows Server 2003.

Здесь у вас есть хороший обзор альтернатив сна (пинг-подход является самым популярным, поскольку он будет работать на каждой машине Windows) но там (по крайней мере) не указано, что (ab) использует команду W32TM (Time Service):

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

0 djangofan [2013-09-05 22:58:00]

Вы можете получить фантазию, поместив сообщение ПАУЗА в строку заголовка:

@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

0 Anonymous Coward [2014-01-29 17:01:00]

Это было протестировано на 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

-2 FluorescentGreen5 [2014-07-28 10:51:00]

ping -n X 127.0.0.1 > nul

Замените X числом секунд + 1.

Например, если вы должны подождать 10 секунд, замените X на 11. Чтобы подождать 5 секунд, используйте 6.

Прочитайте более ранние ответы за миллисекунды.