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

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

Комплект ресурсов сервера 2003 работает с Windows XP (и, вероятно, с w2k)

Martin Beckett 07.07.2009 18:41

Вот несколько вариантов для пакетный файл ждать

Unknown_Guy 25.03.2011 22:41

Microsoft страница загрузки из набора ресурсов Windows 2003 указывает, что он также работает для XP. Боюсь, что нет другого выбора, кроме как использовать «внешнюю» утилиту для ожидания: ничего подобного не встроено в командный процессор XP.

GerG 03.10.2008 13:22

У вас есть несколько вариантов - эмулировать сон с помощью команды ping или загрузить комплект ресурсов Windows, который включает команду sleep. Подробнее здесь: Пакетный файл SLEEP Command

Rudu 25.03.2011 22:30

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

Jack Leow 07.07.2009 18:47

Укажите %1, а не %1%, чтобы ссылаться на первый аргумент командной строки ...

aschipfl 26.01.2017 17:23

Хороший обзор различных методов остановки процесса пакетного файла: robvanderwoude.com/wait.php

1934286 03.01.2019 04:32
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
152
9
144 428
32
Перейти к ответу Данный вопрос помечен как решенный

Ответы 32

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

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

Обратите внимание, что cygwin1.dll не может мирно сосуществовать с разными версиями самого себя. Вам лучше иметь один и только один файл cygwin1.dll на вашем компьютере, иначе вы получите странные сбои.

JesperE 03.10.2008 13:44

Какой набор ресурсов? Кажется, их больше одного. Вы можете обновить свой ответ?

Peter Mortensen 17.04.2017 21:28

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

John Sibly 03.10.2008 17:01

Если "ping 127.0.0.1" не удается, у вас есть более серьезные вещи, чем "сон", о которых нужно беспокоиться - это интерфейс обратной петли, любой RPC, вероятно, сойдет с ума.

Piskvor left the building 04.04.2009 22:26
Ответ принят как подходящий

ОБНОВИТЬ

Команда 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? Спасибо.

Val 19.10.2012 20:17

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

Gras Double 07.08.2017 03:45

Этот подход мог бы обеспечить обходной путь в прошлом, но нативное решение, описанное @Blorgbeard, определенно подходит.

Mike 31.05.2019 15:43

Я использую эту программу сна 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 Dalloul 20.08.2009 12:31

@Wael, если вы говорите об ожидании с интервалом в одну секунду, несколько миллисекунд не имеют значения. И если вы используете cmd.exe для работы в реальном времени, вы заслуживаете всего, что получаете :-)

paxdiablo 20.08.2009 12:34

-w - значение тайм-аута. Это количество миллисекунд ожидания ответа ... нет количество времени ожидания ответа между.

quux 29.07.2011 12:39

@quux, я нигде не заявлял, что -w был тайм-аутом (хотя я допускаю, что некоторые могут сделать вывод, что из-за моей неясности), он фактически используется для ограничения времени цикла, когда возникают сетевые проблемы, которые заставят каждый цикл принимать более, чем его выделил второй. Я добавил абзац в конец, чтобы прояснить это.

paxdiablo 29.07.2011 13:54

проблема в том, что если эхо-запросы возвращают Быстрее, вы не можете ждать одну полную секунду между эхо-запросами. так что ваш цикл ожидания закончится быстрее, чем вы думали

quux 01.08.2011 23:42

@quux, сам ping имеет интервал в одну секунду. Тот факт, что ответы ICMP возвращаются за миллисекунды, не меняет этого. Вы можете изменить интервал (по крайней мере, в Linux), но по умолчанию это одна секунда. Следовательно, ваше беспокойство по поводу быстрых ответов необоснованно.

paxdiablo 02.08.2011 02:23

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

choice /d y /t 5 > nul

К вашему сведению: Choice не входит в состав Windows XP. Он был в Windows 9x, удален из XP и добавлен в Vista и далее.

Devin Burke 05.04.2011 01:58

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

Coding With Style 26.06.2011 03:00

В довершение всего, по крайней мере, известные мне команды CHOICE имеют разные кнопки да / нет по умолчанию в зависимости от языка, на котором они используются, поэтому, если вы полагаетесь на выбор по умолчанию [Y, N] вместо того, чтобы явно указывать его с помощью /C:YN или просто /C:Y, это не сработает, если у кого-то есть, скажем, шведская команда выбора, которая, вероятно, будет выполнять [J, N] по умолчанию. Так что это погрязло во всевозможных неприятностях.

Coding With Style 26.06.2011 03:04

@Coding Протестировано в Win7, и если пользователь нажимает кнопку, он издает звуковой сигнал, однако тайм-аут по-прежнему истекает через дополнительные 5 секунд после того, как пользователь нажал кнопку. Так что, если пользователь продолжает нажимать клавиши, тайм-аут никогда не истечет. Кроме того, в моем случае, когда я использовал это, я считаю, что это скрывает консоль, чтобы пользователь не мог нажать кнопку. В этой системе не было доступа к Python, не было доступа для удаления моего собственного exe в систему (как предлагается в некоторых других ответах), я был довольно ограничен в том, что я мог делать. Итак, что бы вы порекомендовали?

mlsteeves 28.06.2011 21:14

@mlsteeves В каждой Windows, DOS и т. д. есть своя команда выбора, и, как уже отмечалось, она обычно не доступна в Xp. Многие команды выбора имеют несколько иное поведение, а некоторые даже имеют другой синтаксис. Я обычно использую команду ping, когда мне нужно поспать. Это некрасиво, но надежно.

Coding With Style 19.03.2013 02:34

Вы можете использовать слой 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 можно отключить с помощью групповых политик.

Joey 21.04.2012 00:08

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

@ping 127.0.0.1 -n 11 -w 1000 > null

Чем это отличается от ответа paxdiablo?

Peter Mortensen 15.08.2012 11:04

Это не отличается, но ответы здесь взяты из нескольких объединенных вопросов, поэтому не все ответы существовали, когда я отвечал.

Brent Stewart 18.01.2013 20:08

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

Joey 08.01.2015 11:32

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

не работает при использовании без консоли: «ОШИБКА: перенаправление ввода не поддерживается, процесс завершается немедленно».

simpleuser 28.08.2013 03:01

Я имел в виду случаи, когда у вас вообще нет консоли, например, когда командный файл запускается в фоновом режиме через вилку из другого процесса, cygwin crontab или удаленную команду ssh и т. д.

simpleuser 30.08.2013 07:08

О да, я знаю. Я привел пример, чтобы продемонстрировать ошибку :)

Blorgbeard 30.08.2013 08:35

связь в документации для timeout, добавленный @Cristian Ciupitu, частично неверен - в Windows XP этой команды нет.

martineau 02.04.2014 23:49

Тайм-аут у меня не работал без указания полного пути: c: \ windows \ system32 \ timeout

Hello World 03.06.2014 13:00

@HelloWorld, похоже, проблема с вашим% PATH%

Blorgbeard 01.07.2014 00:18

согласно stackoverflow.com/a/1672375/496289, timeout неточен.

Kashyap 02.08.2020 23:36

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

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.

Coding With Style 26.06.2011 03:11

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

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

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

Это должно быть точным, но это способ требует интенсивного использования ЦП. Обычно вам нужна реализация, управляемая прерыванием, чтобы процесс не потреблял циклы ЦП во время ожидания. Это не должно быть проблемой для нечастых коротких ожиданий, что, вероятно, имеет место в большинстве пакетных ситуаций. Но непрерывно выполняющийся процесс с длительным ожиданием может отрицательно сказаться на производительности системы.

dbenham 16.02.2012 01:43

Поскольку он использует системные часы, точность составляет одну секунду. Если указано 2 секунды, задержка может составлять от 2 до 3 секунд (на самом деле 2,99999 ... секунды).

Peter Mortensen 15.08.2012 10:49

Что, если время сейчас 7:59:59, и вы хотите подождать 7 секунд? Похоже, это не учитывается.

ashes999 28.09.2012 22:45

Это потребляет больше процессорного времени, чем подсчитывает системное время. Кроме того, вы выполняете арифметические операции с восьмеричными числами, поскольку минуты и секунды меньше 10 отображаются с начальным 0 в команде TIME.

Andreas 01.03.2013 19:32

@mrt: Если вы просмотрите мое решение, вы поймете, что оно правильно управляет минутами и секундами с ведущим нулем ...

Aacini 02.03.2013 03:59

Да, я заметил операцию по модулю, но скрипт всегда выдает мне эту ошибку несколько раз: Illegal number. Numeric constants are either decimal (17), hexadecimal (0x11) or octal (021) numbers.

Andreas 02.03.2013 13:22

@mrt, @dbenham Проблема, связанная с тем, что этот метод потребляет 100% процессорного времени, может быть уменьшена путем вставки задержки, скажем, 500 мс, с использованием метода ping сразу после метки WAIT:, например PING 1.1.1.1 -n 1 -w 500 > NUL. Это изменение будет означать, что командный файл проводит большую часть времени в пределах тайм-аута ping, что, по-видимому, не потребляет значительных циклов процессора.

rossmcm 22.06.2015 05:00

Ошибка сценария illegal number возникает из-за того, что в команде set пакет предполагает, что любой числовой литерал, начинающийся с 0, является восьмеричный, поэтому 08 и 09 отключают его. Я просто добавляю пару проверок, поэтому, если я хочу получить количество секунд от текущего времени: set Secs=%time:~6,2%, if %Secs%==08 set Secs=8, if %Secs%==09 set Secs=9.

rossmcm 22.06.2015 05:12

@rossmcm: Если вы просматриваете код, секунды берутся следующим образом: SET /A S=1%%C%%100. Если секунды - 08, предыдущая команда SET выполняется следующим образом: SET /A S = 108 % 100, который установил S = 8; это означает, что здесь происходит ошибка Illegal numberникогда. Вы это тестировали?

Aacini 22.06.2015 05:23

@Aacini Я проверил ваш сценарий, и он всегда возвращает ошибку: C:\Temp>delay.bat 5 Ungültige Zahl. Numerische Konstanten sind entweder dezimale (17), hexadezimale (0x11) oder oktale (021) Zahlen. В сообщении об ошибке указано, что номер недействителен. Хотя задержка вроде работает.

Andreas 22.06.2015 08:59

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

Aacini 22.06.2015 15:03

@rossmcm: Не могли бы вы подтвердить, получаете ли вы ошибку illegal number из этого командного файла, и размещать те же данные, которые я запрашивал в предыдущем комментарии, пожалуйста? TIA

Aacini 22.06.2015 15:08

@Aacini Эээ, странно! При удалении @echo off сообщение об ошибке не выводится. Вот результат: pasted.co/757bf8f7

Andreas 22.06.2015 17:01

@mrt: Проблема в том, что ваш %TIME% использует запятую для разделения сотых секунд вместо точки! Просто добавьте запятую в DELIMS=:.," ...

Aacini 22.06.2015 17:14

Используя метод 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.

huysentruitw 28.05.2013 11:41

IP 1.1.1.1 используется CloudFlare, поэтому он будет ждать не 15 с, а около нескольких мс.

hdev 22.03.2019 10:27

... и поэтому вы не выбираете какой-нибудь "точно не занятый" IP-адрес x)

mafu 09.10.2020 16:30

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

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

Хотя это короче, это дубликат принятого ответа.

Peter Mortensen 15.08.2012 11:00

@Peter Mortensen: Это также позволяет вам легко поместить все в одну строку командного файла.

martineau 29.08.2012 21:27

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

@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 28.01.2013 19:03

Моя ошибка, бесконечного цикла не бывает. Однако, как упоминалось в одном из другие ответы, лучше использовать ping что-то не один раз и использовать параметр -w Timeout для времени задержки в миллисекундах, а не параметр -n Count с полным числом повторений.

martineau 28.01.2013 21:25

-w Timeout может быть лучше, но я убедился, что он пингует еще раз, чем указано время.

SuperKael 28.01.2013 21:59

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

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

Лучшее решение, которое должно работать во всех версиях 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 29.03.2014 05:13

Есть лучший способ заснуть с помощью команды 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.

Peter Mortensen 17.04.2017 21:51

Однако я измерил его (используя 100 пингов). Если я использую -n 3 -w 124, фактическое время будет точно (3 + 1) * (124 + 1) = 4 * 125 = 500 мс. Время на удивление стабильно, с точностью до разрешения 10 мс при считывании (по подсказке CMD со временем) - и базовое разрешение определенно лучше, чем 10 мс (не зависит от обычного разрешения в 16 мс).

Peter Mortensen 18.04.2017 01:22

@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-адреса?

Mofi 03.07.2019 11:08

Согласно обсуждению в комментариях здесь, кажется, что 192.0.2.1 не так уж и надежен, и некоторые предполагают, что 127.255.255.255 - лучший выбор. Мысли?

JLRishe 04.07.2019 07:04

Комментарии, упомянутые в сообщении выше, теперь удалены (вероятно, как NLN), но я согласен с изменением 127.255.255.255, поскольку он является широковещательным адресом обратной связи в Windows, который уже назначен по умолчанию (вы можете подтвердить это, запустив route print в cmd и просматривает распечатанную таблицу маршрутизации IPv4).

Hoppeduppeanut 09.07.2019 02:00

timeout /t <seconds> <options>

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

timeout /t 2 /nobreak >NUL

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

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

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

Видимо this command is only available in Windows 7/2008 and the XP Resource Kit (and possibly 8/8.1). The source also claims the ping approach uses less processor time.
martineau 04.06.2014 08:25

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 варианта развертывания:

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

Одним из преимуществ развертывания 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) для более ранних версий ОС.

Другие вопросы по теме