Спать в пакетном файле

150

При написании командного файла для автоматизации чего-либо на 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-подобную команду сна (наконец-то!). В то же время, для тех из нас, кто все еще использует Windows XP, Windows 2000 или (к сожалению) Windows NT , есть ли лучший способ?

Я изменил sleep.pyскрипт в принятом ответе , так что по умолчанию он равен одной секунде, если в командной строке не передано никаких аргументов:

import time, sys

time.sleep(float(sys.argv[1]) if len(sys.argv) > 1 else 1)
Джейсон Этеридж
источник
На странице загрузки Microsoft комплекта ресурсов Windows 2003 указано, что он также работает для XP. Боюсь, что нет другого выбора, кроме как использовать «внешнюю» утилиту для ожидания: нет ничего подобного встроенному в командный процессор XP.
GerG
Набор ресурсов сервера 2003 работает с Windows XP (и, вероятно, с w2k)
Мартин Беккет,
Я сталкивался с той же проблемой в прошлом и сам использовал пинг (с замечанием выше, ясно документирующим, что я понимаю, что это глупо :)).
Джек Лиу
2
У вас есть несколько вариантов - эмулируйте сон с помощью pingкоманды или загрузите набор ресурсов Windows, который включает sleepкоманду. Более подробная информация здесь: Пакетный файл SLEEP Command
Rudu

Ответы:

14

ОБНОВИТЬ

Команда timeout, доступная в Windows Vista и далее, должна быть используемой командой, как описано в другом ответе на этот вопрос. Ниже следует старый ответ.

Старый ответ

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

import time, sys

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

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

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

tzot
источник
32
Почему мы должны писать скрипт на python, когда запрашивается пакетное решение? Как расширение пути может решить проблему, связанную с тем, что у пользователей Windows не установлен интерпретатор python? Спасибо.
Val
6
Ради переносимости, я думаю, что этого решения следует избегать, поскольку есть совершенно прекрасные нативные альтернативы.
Гра Дабл
1
Этот подход мог бы обеспечить обходной путь в прошлом, но нативное решение, описанное @Blorgbeard, определенно является подходящим вариантом.
Майк
227

Команда 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.
Blorgbeard отсутствует
источник
8
не работает в консоли без использования: «ОШИБКА: перенаправление ввода не поддерживается, выход из процесса немедленно».
simpleuser
Я имел в виду случаи, когда у вас вообще нет консоли, например, когда пакетный файл запускается в фоновом режиме через форк из какого-либо другого процесса, cygwin crontab или удаленную команду ssh и т. Д.
simpleuser
1
О да, я знаю. Пример, который я привел, был просто для демонстрации ошибки :)
Blorgbeard отсутствует
3
Ссылка к документации timeout, добавленная @Cristian Ciupitu, частично неправильно - Windows XP не имеет эту команду.
Мартино
1
@HelloWorld, что звучит как проблема с вашим% PATH%
Blorgbeard выходит
21

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

Вы должны быть то , что не существует пинг, и используя -wфлаг так , чтобы он не после этого промежутка времени, не пинг то , что это есть (как локальный хост) -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
Даниил
источник
Мгновенно возвращается сPING: transmit failed. General failure.
huysentruitw
1.1.1.1CloudFlare захватывает IP , так что это будет ждать не 15 секунд, а около нескольких мс.
dhcgn
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%)
Luk
источник
15

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

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

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

Aacini
источник
15
Это должно быть точным, но это интенсивный процесс CPU. Обычно требуется реализация, управляемая прерываниями, чтобы процесс не потреблял циклы ЦП во время ожидания. Это не должно быть проблемой для нечастых коротких ожиданий, как, вероятно, имеет место для большинства пакетных ситуаций. Но непрерывно работающий процесс с длительным ожиданием может оказать негативное влияние на производительность системы.
dbenham
4
Поскольку он использует системные часы, точность составляет одну секунду. Если указано 2 секунды, задержка может составлять от 2 секунд до 3 секунд (фактически 2,99999 ... секунд).
Питер Мортенсен
Что если сейчас время 7:59:59 и вы хотите подождать 7 секунд? Похоже, это не учитывает это.
ashes999
Это потребляет больше процессорного времени, чем системное время. Кроме того, вы выполняете арифметические операции с восьмеричными числами, поскольку минуты и секунды, меньшие 10, отображаются с начальным 0 в TIMEкоманде.
Андреас
2
@mrt: Проблема в том, что вы %TIME%используете запятую, чтобы отделить центсекунды, а не точку! Просто добавьте запятую в DELIMS=:.,"...
Aacini
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;
}
Джон Сибли
источник
10

В Server Fault, был задан похожий вопрос , и решение было:

choice /d y /t 5 > nul
mlsteeves
источник
7
К вашему сведению: выбор не включен в Windows XP. Это было в Windows 9x, удалено из XP и добавлено обратно для Vista.
Девин Берк
7
Я не рекомендовал это вообще. По крайней мере, во всех известных CHOICEмне версиях, если кто-то нажимает кнопку во время ожидания, что иногда делают нетерпеливые люди, то выбор зарегистрирует вход, выдаст системный звуковой сигнал для плохого ввода и остановит таймер обратного отсчета, что означает, что он зависнет. там, если они не нажимают N или Y. И если они просто нажимают одну из этих двух, тогда выбор заканчивается прямо здесь, вместо ожидания 5. Кроме того, этот выбор использует действительно странный синтаксис Vista. Все нормальные команды выбора вместо этого использовали бы CHOICE /T:Y,5 > NULдля этого. Там нет /Dфлага в старых версиях.
Кодирование со стилем
1
Чтобы завершить это, по крайней мере, у команд CHOICE, которые я знаю, есть различные кнопки по умолчанию да / нет, основанные на языке, на котором они появились, так что если вам случается полагаться на выбор по умолчанию [Y, N] вместо того, чтобы явно указать его с помощью /C:YNили просто /C:Yэто не сработает, если у кого-то есть, скажем, шведская команда выбора, которая, вероятно, будет делать [J, N] по умолчанию. Так что это попадает во все виды неприятностей.
Кодирование со стилем
1
@Coding Протестировал это в Win7, и если пользователь нажмет кнопку, он издаст звуковой сигнал, однако через 5 секунд после нажатия кнопки пользователь все равно будет отключен. Поэтому, если пользователь продолжает нажимать клавиши, он никогда не истечет. Кроме того, в моем случае, когда я использовал это, я считаю, что скрыть консоль, чтобы пользователь не мог нажать кнопку. В этой системе не было доступа к Python, не было доступа к удалению моего собственного exe-файла в системе (как предлагалось в некоторых других ответах), я был довольно ограничен в том, что я мог сделать. Итак, что бы вы порекомендовали?
mlsteeves
@mlsteeves У разных Windows, DOS и т. д. есть разные команды выбора, и, как уже было отмечено, они обычно не доступны в Xp. Многие команды выбора имеют слегка различное поведение, а некоторые даже имеют другой синтаксис. Я обычно использую команду ping, когда мне нужно поспать. Это некрасиво, но надежно.
Кодирование со стилем
9

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

if (WScript.Arguments.Count() == 1)
    WScript.Sleep(WScript.Arguments(0)*1000);
else
    WScript.Echo("Usage: cscript wait.js seconds");
Blake7
источник
1
Однако Windows Scripting Host можно отключить с помощью групповых политик.
Джои
8

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

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

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

ping -n 6 localhost >nul 2>&1

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

timeout 6 >nul
детеныш
источник
2
-wв миллисекундах, -nэто просто количество пингов, а время по умолчанию между пингами - секунда.
Джои
8

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

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

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

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

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

paxdiablo
источник
не рекомендуется использовать это для критической обработки в реальном времени. поскольку используется команда PING, возможно, что этот пакетный файл WAIT может работать в течение нескольких миллисекунд
Ваэль Даллул,
12
@ Ваэль, если вы говорите об ожидании на одну секунду, то несколько миллисекунд не будут иметь значения. И если вы используете cmd.exe для работы в реальном времени, вы заслуживаете всего, что получаете :-)
paxdiablo
-w это значение тайм-аута. Это количество миллисекунд ожидания ответа ... а не время ожидания между пингами.
Quux
@quux, нигде я не утверждал, что -wбыл тайм-аут (хотя я допускаю, что некоторые могут сделать вывод, что из-за моей неясности), он фактически используется для ограничения времени цикла, когда возникают проблемы с сетью, из-за которых каждый цикл занимает больше, чем выделено второй. Я добавил параграф до конца, чтобы прояснить это.
paxdiablo
проблема в том, что если пинг возвращается быстрее , вы не можете ждать одну полную секунду между пингами. так что ваш цикл ожидания закончится быстрее, чем вы думали
quux
7

Есть лучший способ спать, используя пинг. Вы захотите пропинговать адрес, который не существует, поэтому вы можете указать время ожидания с точностью до миллисекунды. К счастью, такой адрес определен в стандарте (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

Mafu
источник
Да, это легче написать и понять, чем добавить его к -nпараметру.
Питер Мортенсен
Однако я измерил это (используя 100 пингов). Если я использую -n 3 -w 124, фактическое время будет точно (3 + 1) * (124 + 1) = 4 * 125 = 500 мс. Синхронизация на удивление стабильна и точно соответствует разрешению 10 мс при считывании (по подсказке CMD со временем), а базовое разрешение определенно лучше, чем 10 мс (не зависит от обычного разрешения тиков 16 мс).
Питер Мортенсен
@mafu То, что 192.0.2.0/24 не следует использовать, не означает, что его нельзя использовать, и поэтому на самом деле не гарантируется, что нет ответа на эхо-запрос (ы). Например, для любого ПК с Windows настройте статический IPv4-адрес 192.0.2.1 и маску подсети 255.255.255.0 и подключите сетевой адаптер к любому другому устройству. Достаточно простого переключателя, к которому больше ничего не подключено. Затем запустите ping 192.0.2.1на этом ПК с Windows, и вы увидите, что стек TCP / IP Windows отвечает на эхо-запросы. Сколько людей знают, что 192.0.2.0/24 не следует использовать для статического адреса IPv4?
Мофи
1
Согласно обсуждению в комментариях здесь , кажется, что 192.0.2.1 не так уж и надежен, и некоторые полагают, что 127.255.255.255 - лучший выбор. Мысли?
JLRishe
Комментарии, упомянутые в посте выше, теперь удалены (вероятно, как NLN), но я согласен с изменением, 127.255.255.255поскольку это адрес широковещательного шлейфа в Windows, который уже назначен по умолчанию (Вы можете подтвердить это, запустив route printв cmd и просматривая таблицу маршрутов IPv4, которую он печатает).
Hoppeduppeanut
6

Если у вас есть 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 мс).

Найл Коннотон
источник
6
timeout /t <seconds> <options>

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

timeout /t 2 /nobreak >NUL

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

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

редактировать: как @martineau указывает в комментариях , timeoutкоманда доступна только в Windows 7 и выше. Кроме того, pingкоманда использует меньше процессорного времени, чем timeout. Я все еще верю в использование, timeoutгде это возможно, хотя, поскольку это более читабельно, чем ping«взломать». Узнайте больше здесь .

mgthomas99
источник
2
По-видимому, эта команда доступна только в Windows 7/2008 и XP Resource Kit (и, возможно, 8 / 8.1). Источник также утверждает, что pingподход использует меньше процессорного времени.
Мартино
5

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

@ping 127.0.0.1 -n 11 -w 1000 > null
Брент Стюарт
источник
Чем это отличается от ответа Паксдиабло?
Питер Мортенсен
2
Это не отличается, но ответы здесь от нескольких объединенных вопросов, поэтому не все ответы существовали, когда я ответил.
Брент Стюарт
4

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

@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>
SuperKael
источник
Он пингует себя несколько раз, ожидая секунду между каждым пингом, а затем возвращается к вызывающей программе. Я не вижу бесконечный цикл, но я сам его проверил.
СуперКаэль
Моя ошибка, нет бесконечного цикла. Однако, как упомянуто в одном из других ответов , лучше использовать pingчто-то не один раз, и использовать -w Timeoutопцию для времени задержки в миллисекундах, а не -n Countопцию полного числа повторов.
Мартино
-w Timeout может быть и лучше, но я убедился, что он пингует еще раз, чем введенное время.
СуперКаэль
4

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

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

Дарен Томас
источник
2
Обратите внимание, что cygwin1.dll не может мирно сосуществовать с различными версиями самого себя. Вам лучше иметь один и только один cygwin1.dll на вашем компьютере, иначе вы получите странные сбои.
JesperE
Какой ресурсный комплект? Кажется, их больше одного. Можете ли вы обновить свой ответ?
Питер Мортенсен
3

Мне нравится ответ Аасини . Я добавил его для обработки дня, а также включил обработку секунд ( %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
Hossy
источник
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");
            }
        }
    }
}
Liam
источник
3

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

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

perl -e "sleep 7"

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

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

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

Питер Мортенсен
источник
2

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

python -c "import time;time.sleep(6.5)"
Алекс Робинсон
источник
Короче, это дубликат принятого ответа.
Питер Мортенсен
@ Питер Мортенсен: Это также позволяет легко помещать все в одну строку командного файла.
Мартино
2

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

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

Найти уже готовый исполняемый файл для сна - самый удобный способ. Просто поместите его в свою папку 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);

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

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

Tooony
источник
1
Sleep доступен в .net framework - взгляните на класс потока, например: using System.Threading; .... Thread.Sleep (1000);
Джон Симбл
2
Если «ping 127.0.0.1» завершается неудачно, у вас есть более серьезные проблемы, чем «сон», о которых стоит беспокоиться - это интерфейс с обратной связью, все, что RPC, вероятно, сойдет с ума.
Писквор покинул здание
2

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

timeout numbersofseconds /nobreak > nul
Тато
источник
Не работает на XP Pro ...'timeout' is not recognized as an internal or external command, operable program or batch file.
martineau
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
Andry
источник
1

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

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

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

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

Крис Москини
источник
3
Я повторю себя здесь: я не рекомендовал это вообще. В известных CHOICEмне версиях, если кто-то нажимает клавишу во время ожидания, что иногда делают нетерпеливые люди, то выбор прочитает ввод, выдаст системный звуковой сигнал о неправильном вводе и остановит обратный отсчет, поэтому он зависнет, если не нажать Y. И если они просто нажимают Y, то выбор заканчивается тут, вместо того, чтобы ждать 5. Кроме того, этот выбор использует действительно странный синтаксис Vista. Обычные команды выбора вместо этого используют CHOICE /T:Y,5 > NULдля этого. (В старых версиях нет флага / D). И если у вас Vista, используйте TIMEOUTвместо этого.
Кодирование со стилем
1

Вы также можете использовать файл .vbs для определенных таймаутов:

Код ниже создает файл .vbs. Поместите это в верхней части кода rbatch:

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

Затем приведенный ниже код открывает файл .vbs и указывает, как долго ждать:

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

В приведенном выше коде «1000» - это значение временной задержки, отправляемой в файл .vbs в миллисекундах, например, 1000 мс = 1 с. Вы можете изменить эту часть так долго, как вы хотите.

Код ниже удаляет файл .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"
EpicNinjaCheese
источник
1

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

Здесь у вас есть хороший обзор альтернатив сна (подход ping является наиболее популярным, поскольку он будет работать на каждой машине с 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

С помощью 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);
}
npocmaka
источник
1

Есть много способов сделать сон 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

Вместо этого используется localhostверсия IPv6 .

Есть много способов выполнить это действие. Однако я предпочитаю метод 1 для Windows Vista и более поздних версий и наиболее часто используемый метод (метод 2) для более ранних версий ОС.

Lumito
источник
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
djangofan
источник
0

Это было проверено на 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
Анонимный трус
источник
0

Поскольку другие предлагают сторонние программы (Python, Perl, пользовательские приложения и т. Д.), Другой вариант - GNU CoreUtils для Windows, доступный по адресу http://gnuwin32.sourceforge.net/packages/coreutils.htm .

2 варианта размещения:

  1. Установите полный пакет (который будет включать полный пакет CoreUtils, зависимости, документацию и т. Д.).
  2. Устанавливайте только двоичный файл «sleep.exe» и необходимые зависимости (для получения зависимостей используйте зависимость от.exe).

Одним из преимуществ развертывания CoreUtils является то, что вы дополнительно получите множество других программ, которые полезны для сценариев (пакет Windows оставляет желать лучшего).

codesniffer
источник