При написании командного файла для автоматизации чего-либо в окне 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)
Вот несколько вариантов для пакетный файл ждать
Проверить: Реализация команды WAIT в пакетном файлеПакетный файл SLEEP Command
Microsoft страница загрузки из набора ресурсов Windows 2003 указывает, что он также работает для XP. Боюсь, что нет другого выбора, кроме как использовать «внешнюю» утилиту для ожидания: ничего подобного не встроено в командный процессор XP.
У вас есть несколько вариантов - эмулировать сон с помощью команды ping или загрузить комплект ресурсов Windows, который включает команду sleep. Подробнее здесь: Пакетный файл SLEEP Command
Я столкнулся с той же проблемой в прошлом и сам использовал ping (с замечанием выше, четко документирующим, что я понимаю, что это глупо :)).
Укажите %1, а не %1%, чтобы ссылаться на первый аргумент командной строки ...
Хороший обзор различных методов остановки процесса пакетного файла: robvanderwoude.com/wait.php






Набор ресурсов всегда включал это. По крайней мере, с Windows 2000.
Кроме того, в пакете Cygwin есть sleep - вставьте его в ваш PATH и включите cygwin.dll (или как там он называется) и путь к делу!
Обратите внимание, что cygwin1.dll не может мирно сосуществовать с разными версиями самого себя. Вам лучше иметь один и только один файл cygwin1.dll на вашем компьютере, иначе вы получите странные сбои.
Какой набор ресурсов? Кажется, их больше одного. Вы можете обновить свой ответ?
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%)
У меня возникла аналогичная проблема, но я просто создал очень короткое консольное приложение на 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;
}
Использование пинг хорошо, если вы просто хотите «немного подождать». Это связано с тем, что вы зависите от других функций внизу, таких как работа вашей сети и тот факт, что на 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() включен в стандартную библиотеку, а в Visual Studio C от Microsoft функция называется Sleep(), если мне не изменяет память. ;-) Эти двое принимают аргумент в секундах, а не в миллисекундах, как в двух предыдущих объявлениях.
Сон доступен в платформе .net - взгляните на класс потока, например: using System.Threading; .... Thread.Sleep (1000);
Если "ping 127.0.0.1" не удается, у вас есть более серьезные вещи, чем "сон", о которых нужно беспокоиться - это интерфейс обратной петли, любой RPC, вероятно, сойдет с ума.
Команда 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 вы можете редактировать его в:
Мой компьютер → Свойства (меню) → Дополнительно (вкладка) → Переменные среды (кнопка) → Системные переменные (рамка)
почему мы должны писать скрипт на Python, когда запрашивается пакетное решение? Как расширение пути может решить проблему того, что у пользователей Windows не установлен интерпретатор Python? Спасибо.
Я думаю, что ради переносимости этого решения следует избегать, поскольку есть прекрасные собственные альтернативы.
Этот подход мог бы обеспечить обходной путь в прошлом, но нативное решение, описанное @Blorgbeard, определенно подходит.
Я использую эту программу сна 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");
}
}
}
}
Еще более легким, чем решение Python, является Perl один лайнер.
Чтобы засыпать на семь секунд, введите это в сценарий BAT:
perl -e "sleep 7"
Это решение обеспечивает разрешение только в одну секунду.
Если вам нужно более высокое разрешение, используйте Time :: HiRes.
модуль из CPAN. Он обеспечивает usleep(), который спит в
микросекунды и nanosleep(), который спит в наносекундах
(обе функции принимают только целочисленные аргументы). Увидеть
Stack Overflow вопрос Как мне поспать миллисекунду в Perl? для получения дополнительной информации.
Я использую ActivePerl много лет. Очень легко установить.
Вы можете использовать ping:
ping 127.0.0.1 -n 11 -w 1000 >nul: 2>nul:
Подождет 10 секунд.
Причина, по которой вы должны использовать 11, заключается в том, что первый пинг выключается сразу, а не через одну секунду. Число всегда должно быть на единицу больше, чем количество секунд, которое вы хотите подождать.
Имейте в виду, что цель -w - не ждать ни секунды. Это необходимо для того, чтобы вы не ждали более более одной секунды в случае возникновения сетевых проблем. ping сам по себе будет отправлять один пакет ICMP в секунду. Вероятно, это не требуется для localhost, но от старых привычек трудно избавиться.
не рекомендуется использовать это для критической обработки в реальном времени. поскольку используется команда PING, возможно, что этот командный файл WAIT может работать в течение нескольких миллисекунд.
@Wael, если вы говорите об ожидании с интервалом в одну секунду, несколько миллисекунд не имеют значения. И если вы используете cmd.exe для работы в реальном времени, вы заслуживаете всего, что получаете :-)
-w - значение тайм-аута. Это количество миллисекунд ожидания ответа ... нет количество времени ожидания ответа между.
@quux, я нигде не заявлял, что -w был тайм-аутом (хотя я допускаю, что некоторые могут сделать вывод, что из-за моей неясности), он фактически используется для ограничения времени цикла, когда возникают сетевые проблемы, которые заставят каждый цикл принимать более, чем его выделил второй. Я добавил абзац в конец, чтобы прояснить это.
проблема в том, что если эхо-запросы возвращают Быстрее, вы не можете ждать одну полную секунду между эхо-запросами. так что ваш цикл ожидания закончится быстрее, чем вы думали
@quux, сам ping имеет интервал в одну секунду. Тот факт, что ответы ICMP возвращаются за миллисекунды, не меняет этого. Вы можете изменить интервал (по крайней мере, в Linux), но по умолчанию это одна секунда. Следовательно, ваше беспокойство по поводу быстрых ответов необоснованно.
При сбое сервера, был задан аналогичный вопрос, и решение было:
choice /d y /t 5 > nul
К вашему сведению: Choice не входит в состав Windows XP. Он был в Windows 9x, удален из XP и добавлен в Vista и далее.
Я вообще этого не рекомендую. По крайней мере, во всех известных мне версиях CHOICE, если кто-то нажимает кнопку во время ожидания, что иногда делают нетерпеливые люди, то choice зарегистрирует ввод, подаст системный звуковой сигнал при неправильном вводе и остановит таймер обратного отсчета, что означает, что он будет висеть там, если они не нажимают N или Y. И если они просто нажимают одну из этих двух, тогда выбор заканчивается прямо здесь, вместо ожидания 5. Кроме того, этот выбор использует действительно странный синтаксис Vista. Вместо этого все обычные команды выбора будут использовать для этого CHOICE /T:Y,5 > NUL. В старых версиях флаг /D отсутствует.
В довершение всего, по крайней мере, известные мне команды CHOICE имеют разные кнопки да / нет по умолчанию в зависимости от языка, на котором они используются, поэтому, если вы полагаетесь на выбор по умолчанию [Y, N] вместо того, чтобы явно указывать его с помощью /C:YN или просто /C:Y, это не сработает, если у кого-то есть, скажем, шведская команда выбора, которая, вероятно, будет выполнять [J, N] по умолчанию. Так что это погрязло во всевозможных неприятностях.
@Coding Протестировано в Win7, и если пользователь нажимает кнопку, он издает звуковой сигнал, однако тайм-аут по-прежнему истекает через дополнительные 5 секунд после того, как пользователь нажал кнопку. Так что, если пользователь продолжает нажимать клавиши, тайм-аут никогда не истечет. Кроме того, в моем случае, когда я использовал это, я считаю, что это скрывает консоль, чтобы пользователь не мог нажать кнопку. В этой системе не было доступа к Python, не было доступа для удаления моего собственного exe в систему (как предлагается в некоторых других ответах), я был довольно ограничен в том, что я мог делать. Итак, что бы вы порекомендовали?
@mlsteeves В каждой Windows, DOS и т. д. есть своя команда выбора, и, как уже отмечалось, она обычно не доступна в Xp. Многие команды выбора имеют несколько иное поведение, а некоторые даже имеют другой синтаксис. Я обычно использую команду ping, когда мне нужно поспать. Это некрасиво, но надежно.
Вы можете использовать слой 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");
Однако Windows Scripting Host можно отключить с помощью групповых политик.
Просто поместите это в свой командный файл, где хотите подождать.
@ping 127.0.0.1 -n 11 -w 1000 > null
Чем это отличается от ответа paxdiablo?
Это не отличается, но ответы здесь взяты из нескольких объединенных вопросов, поэтому не все ответы существовали, когда я отвечал.
В зависимости от ваших требований к совместимости используйте ping:
ping -n <numberofseconds+1> localhost >nul 2>&1
например чтобы подождать 5 секунд, используйте
ping -n 6 localhost >nul 2>&1
или в Windows 7 или новее используйте timeout:
timeout 6 >nul
-w выражается в миллисекундах, -n - это просто количество проверок связи, а время по умолчанию между проверками связи - секунда.
Команда 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.
не работает при использовании без консоли: «ОШИБКА: перенаправление ввода не поддерживается, процесс завершается немедленно».
Я имел в виду случаи, когда у вас вообще нет консоли, например, когда командный файл запускается в фоновом режиме через вилку из другого процесса, cygwin crontab или удаленную команду ssh и т. д.
О да, я знаю. Я привел пример, чтобы продемонстрировать ошибку :)
связь в документации для timeout, добавленный @Cristian Ciupitu, частично неверен - в Windows XP этой команды нет.
Тайм-аут у меня не работал без указания полного пути: c: \ windows \ system32 \ timeout
@HelloWorld, похоже, проблема с вашим% PATH%
согласно stackoverflow.com/a/1672375/496289, timeout неточен.
Я впечатлен этим:
http://www.computerhope.com/batch.htm#02
choice /n /c y /d y /t 5 > NUL
Технически вы говорите команде choice принимать только y. По умолчанию это y, чтобы сделать это за 5 секунд, чтобы не отображать подсказки и вывести все, что он говорит, в NUL (например, нулевой терминал в Linux).
Я повторю себе здесь: я вообще этого не рекомендую. В версиях CHOICE, которые я знаю, если кто-то нажимает клавишу во время ожидания, что иногда делают нетерпеливые люди, то choice прочитает ввод, подаст системный звуковой сигнал при неправильном вводе и остановит обратный отсчет, поэтому он зависнет, если они не нажмут Y И если они просто нажимают Y, тогда выбор заканчивается прямо здесь, вместо того, чтобы ждать 5. Кроме того, этот выбор использует действительно странный синтаксис Vista. Вместо этого в обычных командах выбора используется CHOICE /T:Y,5 > NUL. (В старых версиях флага / D отсутствует.) А если у вас Vista, используйте TIMEOUT.
Я не согласен с ответами, которые нашел здесь.
Я использую следующий метод, полностью основанный на возможностях Windows XP для задержки в пакетном файле:
ЗАДЕРЖКА.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
Вы также можете вставить день в расчет, чтобы этот метод также работал, когда интервал задержки превышает полночь.
Это должно быть точным, но это способ требует интенсивного использования ЦП. Обычно вам нужна реализация, управляемая прерыванием, чтобы процесс не потреблял циклы ЦП во время ожидания. Это не должно быть проблемой для нечастых коротких ожиданий, что, вероятно, имеет место в большинстве пакетных ситуаций. Но непрерывно выполняющийся процесс с длительным ожиданием может отрицательно сказаться на производительности системы.
Поскольку он использует системные часы, точность составляет одну секунду. Если указано 2 секунды, задержка может составлять от 2 до 3 секунд (на самом деле 2,99999 ... секунды).
Что, если время сейчас 7:59:59, и вы хотите подождать 7 секунд? Похоже, это не учитывается.
Это потребляет больше процессорного времени, чем подсчитывает системное время. Кроме того, вы выполняете арифметические операции с восьмеричными числами, поскольку минуты и секунды меньше 10 отображаются с начальным 0 в команде TIME.
@mrt: Если вы просмотрите мое решение, вы поймете, что оно правильно управляет минутами и секундами с ведущим нулем ...
Да, я заметил операцию по модулю, но скрипт всегда выдает мне эту ошибку несколько раз: Illegal number. Numeric constants are either decimal (17), hexadecimal (0x11) or octal (021) numbers.
@mrt, @dbenham Проблема, связанная с тем, что этот метод потребляет 100% процессорного времени, может быть уменьшена путем вставки задержки, скажем, 500 мс, с использованием метода ping сразу после метки WAIT:, например PING 1.1.1.1 -n 1 -w 500 > NUL. Это изменение будет означать, что командный файл проводит большую часть времени в пределах тайм-аута ping, что, по-видимому, не потребляет значительных циклов процессора.
Ошибка сценария illegal number возникает из-за того, что в команде set пакет предполагает, что любой числовой литерал, начинающийся с 0, является восьмеричный, поэтому 08 и 09 отключают его. Я просто добавляю пару проверок, поэтому, если я хочу получить количество секунд от текущего времени: set Secs=%time:~6,2%, if %Secs%==08 set Secs=8, if %Secs%==09 set Secs=9.
@rossmcm: Если вы просматриваете код, секунды берутся следующим образом: SET /A S=1%%C%%100. Если секунды - 08, предыдущая команда SET выполняется следующим образом: SET /A S = 108 % 100, который установил S = 8; это означает, что здесь происходит ошибка Illegal numberникогда. Вы это тестировали?
@Aacini Я проверил ваш сценарий, и он всегда возвращает ошибку: C:\Temp>delay.bat 5 Ungültige Zahl. Numerische Konstanten sind entweder dezimale (17), hexadezimale (0x11) oder oktale (021) Zahlen. В сообщении об ошибке указано, что номер недействителен. Хотя задержка вроде работает.
@mrt: Это странно. Не могли бы вы удалить строку @ECHO OFF, запустить код с 1 секундой и опубликовать строки FOR и SET, которые вызывают ошибку? Например: FOR /F "TOKENS=1-3 DELIMS=:." %A IN (" 6:56:34.14") DO SET /A H=%A, M=1%B%100,S=1%C%100, CURRENT=(H*60+M)*60+S и SET /A H= 6, M=156%100, S=134%100, CURRENT=(H*60+M)*60+S.
@rossmcm: Не могли бы вы подтвердить, получаете ли вы ошибку illegal number из этого командного файла, и размещать те же данные, которые я запрашивал в предыдущем комментарии, пожалуйста? TIA
@Aacini Эээ, странно! При удалении @echo off сообщение об ошибке не выводится. Вот результат: pasted.co/757bf8f7
@mrt: Проблема в том, что ваш %TIME% использует запятую для разделения сотых секунд вместо точки! Просто добавьте запятую в DELIMS=:.," ...
Используя метод 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
Мгновенно возвращается с PING: transmit failed. General failure.
IP 1.1.1.1 используется CloudFlare, поэтому он будет ждать не 15 с, а около нескольких мс.
... и поэтому вы не выбираете какой-нибудь "точно не занятый" IP-адрес x)
Или командная строка Python, например, на 6 с половиной секунд:
python -c "import time;time.sleep(6.5)"
Хотя это короче, это дубликат принятого ответа.
@Peter Mortensen: Это также позволяет вам легко поместить все в одну строку командного файла.
В Блокноте напишите:
@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>
Он многократно пингует себя, ожидая секунду между каждым эхо-запросом, а затем возвращается к вызывающей программе, я не вижу бесконечного цикла, но я тестировал его сам.
Моя ошибка, бесконечного цикла не бывает. Однако, как упоминалось в одном из другие ответы, лучше использовать ping что-то не один раз и использовать параметр -w Timeout для времени задержки в миллисекундах, а не параметр -n Count с полным числом повторений.
-w Timeout может быть лучше, но я убедился, что он пингует еще раз, чем указано время.
Мне нравится Ответ Аачини. Я добавил к нему, чтобы обрабатывать день, а также разрешил ему обрабатывать сантисекунды (%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
Если в вашей системе есть 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 мс).
Вы можете пофантазировать, поместив сообщение ПАУЗА в строку заголовка:
@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 Vista, у вас есть команды ТАЙМ-АУТ и СПАТЬ, но чтобы использовать их в 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);
}
Вы также можете использовать файл .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"
Это было протестировано на Windows XP SP3 и Windows 7 и использует CScript. Я поставил некоторые меры предосторожности, чтобы избежать подсказок del "". (/q был бы опасен)
Подождите одну секунду:
sleepOrDelayExecution 1000
Подождите 500 мс, а затем выполните следующие действия:
sleepOrDelayExecution 500 dir \ /s
@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
Лучшее решение, которое должно работать во всех версиях Windows после Windows 2000:
timeout numbersofseconds /nobreak > nul
Не работает на XP Pro ... 'timeout' is not recognized as an internal or external command, operable program or batch file.
Есть лучший способ заснуть с помощью команды ping. Вы захотите проверить связь с несуществующим адресом, поэтому вы можете указать тайм-аут с точностью до миллисекунды. К счастью, такой адрес определен в стандарте (RFC 3330), и это 192.0.2.x. Это не выдумка, это действительно адрес с единственной целью - не существовать. Чтобы было понятно, это применимо даже в локальных сетях.
192.0.2.0/24 - This block is assigned as "TEST-NET" for use in documentation and example code. It is often used in conjunction with domain names example.com or example.net in vendor and protocol documentation. Addresses within this block should not appear on the public Internet.
Чтобы засыпать на 123 миллисекунды, используйте ping 192.0.2.1 -n 1 -w 123 >nul
Обновление: согласно комментариям, есть также 127.255.255.255.
Да, это легче написать и понять, чем иметь добавить одну для параметра -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, и вы увидите, что стек Windows TCP / IP отвечает на эхо-запросы. Сколько людей знают, что 192.0.2.0/24 не следует использовать для статического IPv4-адреса?
Согласно обсуждению в комментариях здесь, кажется, что 192.0.2.1 не так уж и надежен, и некоторые предполагают, что 127.255.255.255 - лучший выбор. Мысли?
Комментарии, упомянутые в сообщении выше, теперь удалены (вероятно, как NLN), но я согласен с изменением 127.255.255.255, поскольку он является широковещательным адресом обратной связи в Windows, который уже назначен по умолчанию (вы можете подтвердить это, запустив route print в cmd и просматривает распечатанную таблицу маршрутизации IPv4).
timeout /t <seconds> <options>
Например, чтобы сценарий выполнял непрерывное двухсекундное ожидание:
timeout /t 2 /nobreak >NUL
Это означает, что скрипт подождет 2 секунды, прежде чем продолжить.
По умолчанию нажатие клавиши прерывает тайм-аут, поэтому используйте переключатель /nobreak, если вы не хотите, чтобы пользователь мог прерывать (отменять) ожидание. Кроме того, тайм-аут будет предоставлять посекундные уведомления, чтобы уведомить пользователя о том, сколько времени осталось ждать; это можно удалить, передав команду по конвейеру NUL.
редактировать: Как @martineauуказывает в комментариях, команда timeout доступна только в Windows 7 и выше. Кроме того, команда ping использует меньше процессорного времени, чем timeout. Я все еще верю в использование timeout там, где это возможно, поскольку он более читабелен, чем «взлом» ping. Узнать больше здесь.
ping approach uses less processor time.
ping -n X 127.0.0.1 > nul
Замените X на количество секунд + 1.
Например, если вы подождите 10 секунд, замените X на 11. Чтобы подождать 5 секунд, используйте 6.
Прочтите предыдущие ответы за миллисекунды.
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
Поскольку другие предлагают сторонние программы (Python, Perl, пользовательское приложение и т. д.), Другим вариантом является GNU CoreUtils для Windows, доступный по адресу http://gnuwin32.sourceforge.net/packages/coreutils.htm.
2 варианта развертывания:
Одним из преимуществ развертывания CoreUtils является то, что вы дополнительно получите множество других программ, которые полезны для написания сценариев (пакет Windows оставляет желать лучшего).
Просто для удовольствия, если у вас установлен Node.js, вы можете использовать
node -e 'setTimeout(a => a, 5000)'
спать на 5 секунд. Он работает на Mac с Node v12.14.0.
Есть много способов выполнить 'спать' в cmd / batch:
Мой любимый:
TIMEOUT /NOBREAK 5 >NUL 2>NUL
Это остановит консоль на 5 секунд без какого-либо вывода.
Наиболее используемое:
ping localhost -n 5 >NUL 2>NUL
Это будет пытаться установить соединение с localhost 5 раз. Поскольку он размещен на вашем компьютере, он всегда будет достигать хоста, поэтому каждую секунду он будет пробовать новый каждую секунду. Флаг -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
Вместо этого используется версия IPv6 localhost.
Есть много способов выполнить это действие. Однако я предпочитаю метод 1 для Windows Vista и более поздних версий и наиболее часто используемый метод (метод 2) для более ранних версий ОС.
Комплект ресурсов сервера 2003 работает с Windows XP (и, вероятно, с w2k)