Як заснути в пакетному файлі?


132

Як призупинити виконання на деякий час у пакетному файлі Windows між командою та наступною?


Це призначено стати канонічним? Якщо так, то може бути доречним якийсь пояснювальний текст.
Джон Гарденєр

2
"Пояснювальний текст" як у?
Массімо

2
Більшість, якщо не всі, канонічні питання, які я бачив, включають текст, що описує наміри цього питання.
Джон Гарденєр

Або якийсь текст, що пояснює ситуацію ... Це здебільшого допомога в SEO, але також допомагає формувати потенційні відповіді.
Chris S

2
SEO працює просто чудово. Перший хіт для мене в пошуку Google.
jbo5112

Відповіді:


194

Правильний спосіб сну в пакетному файлі - це використання timeoutкоманди, введеної в Windows 2000.

Зачекати десь від 29 до 30 секунд :

timeout /t 30

Час очікування буде перервано, якщо користувач натисне яку-небудь клавішу; однак команда також приймає необов'язковий перемикач /nobreak, який фактично ігнорує все, що може натиснути користувач, крім явного CTRL-C:

timeout /t 30 /nobreak

Крім того, якщо ви не хочете, щоб команда друкувала свій відлік на екрані, ви можете перенаправити його вихід на NUL:

timeout /t 30 /nobreak > NUL

6
Команда тайм-аута не працює з Windows XP навіть із встановленим набором ресурсів 2003, а команда сну не працює в Windows 7, тому команда ping все ще може бути корисною, якщо ви використовуєте пакетний файл як на Win7, так і на WinXP.

12
тайм-аут не працює в неінтерактивних сценаріях: "ПОМИЛКА: переадресація вводу не підтримується, негайно виходить з процесу." тому іноді краще використовувати хак з "ping".
iMysak

14

Оскільки це стосується і тут, я скопію свою відповідь з іншого сайту .

Якщо ви хочете використовувати пінг, є кращий спосіб. Вам потрібно буде ввести адресу, яка не існує, тому ви можете вказати час очікування з точністю до мілісекунд. На щастя, така адреса визначена у стандарті (RFC 3330), і вона є 192.0.2.x. Це не створено, це дійсно адреса з єдиною метою неіснуючої (вона може бути не зрозумілою, але вона застосовується навіть у локальних мережах):

192.0.2.0/24 - Цей блок призначений як "TEST-NET" для використання в документації та прикладі коду. Він часто використовується разом із доменними іменами example.com або example.net у документації щодо постачальників та протоколів. Адреси в цьому блоці не повинні з’являтися в загальнодоступному Інтернеті.

Щоб заснути протягом 123 мілісекунд, використовуйте ping 192.0.2.1 -n 1 -w 123 >nul


3
Будь ласка, не робіть цього, навіть якщо це трохи краще, ніж набирати реальну адресу. Pingпросто неправильний інструмент для роботи.
Массімо

1
@Massimo Це, швидше за все, не те, що було призначено зробити :) Але я думаю, що це все-таки хороше рішення - воно працює краще, ніж час очікування в деяких сценаріях (зокрема, з більшою роздільною здатністю). Крім того, це стало досить відомим, тому більшість людей не будуть дуже здивовані (тобто розгублені), побачивши це у вашому пакетному файлі.
мафу

2
@Massimo Добре! Я думаю, у нас просто різні погляди. Якщо ви не заперечуєте, я все-таки залишу цю відповідь, оскільки, здається, це краще, ніж пінг-прогулки localhost n разів, як це найчастіше описано.
mafu

7
timeout - це правильне рішення для операційних систем, на яких він працює. ping - єдине рішення, яке працює з 5.1-6.3. Якщо 25% систем все ще знаходяться в системі 5.1, час очікування не є «правильним способом».
Вірмвуд

3
тайм-аут є неправильним рішенням для будь-якої операційної системи, оскільки він фатально порушений навіть у Windows 10. Яке використання - це команда, яка виходить з ладу лише тому, що вхід перенаправлений?
Гаррі Джонстон

8

Ви також можете вставити ping до localhost. На це знадобиться 4 секунди (за замовчуванням). Деякі вважаються хитрістю, але все-таки добре працює.

Команда:
ping 127.0.0.1


6
Ем ... вся мета цього питання / відповіді полягала саме в тому, щоб виправити два інші питання, на які це прийнято як відповідь, але їх більше не можна виправити, оскільки їх ОП вже не існує.
Массімо

6
Хоча це буде працювати, це еквівалент забивання гвинта молотком. Неправильний інструмент може працювати, але все-таки неправильний.
voretaq7

1
@MarkAllen Іншими словами, Windows NT4, 95, 98, ME та старіші?
Кріс МакКаун

5
@MarkAllen - технічно вам потім доведеться турбуватися про те, pingпоставляється він із вашою ОС. Якщо ви стурбовані досить про '95 '98 або ME , то ви повинні бути в рівній мірі стурбовані 6.22 , яка не має pingні
Марк Хендерсон

4
@MarkHenderson Простіше (мені) запам’ятати, підтримує чи не той чи інший випуск ОС підтримує TCP / IP, ніж пам’ятати, включає він чи ні команду, про яку я раніше не чув. Ти знаєш?
Марк Аллен

2

Відмова від відповідальності : це не "ідеальне" рішення, тому не турбуйте мене над головою, як це робиться тим, хто рекомендує ping...

Коли це можливо, використовуйте timeoutнапевно. Але як зазначається в коментарях, це не завжди варіант (наприклад, в неінтерактивному режимі). Після цього я погоджуюсь, що ping«хитрощі» - це, мабуть, наступний найкращий варіант, оскільки це дуже просто. Це означає, що я пропоную інший варіант ... вставити якийсь сценарій VB .

В основі цього рішення є всілякі сфери застосування поза цим. Часто VBS може робити речі, які партія не може, або принаймні робити це з різко більшою легкістю. Використовуючи техніку, проілюстровану тут, ви можете змішати два (не "плавно", а "функціонально" ...).

Ось один вкладиш, щоб створити темп-скрипт, виконати його, а потім видалити. Сценарій виконує сон для вас (у цьому прикладі протягом 3 секунд).

echo WScript.Sleep 3000 > %temp%\sleep.vbs & cscript %temp%\sleep.vbs %sleepMs% //B & del %temp%\sleep.vbs

Ось в основному те саме, написане трохи інакше:

set sleepMs=3000 & set sleepVbs=%temp%\sleep.vbs & echo WScript.Sleep WScript.Arguments(0) > %sleepVbs% & cscript %sleepVbs% %sleepMs% //B & del %sleepVbs%

І тоді нарешті, начебто ping, CScriptсама має варіант тайм-аута! Отже, якщо ви введете нескінченний цикл у сценарій, ви можете дозволити інтерпретатору виконувати тривалість. Зауважте, це "зайнята" операція, яка харчується процесором, і тому я не рекомендую її використовувати, коли ви можете використовувати WScript.Sleepпроцедуру, але я представляю це як концептуальний варіант заради повноти:

set sleepSec=3 & set sleepVbs=%temp%\sleep.vbs & echo While True > %sleepVbs% & echo Wend >> %sleepVbs% & cscript %sleepVbs% //B //T:%sleepSec% & del %sleepVbs%

Ви знаєте ... ви могли це зробити в повному складі, я думаю, без необхідності писати файл.
Гаррі Джонстон

Так, це, ймовірно, ще одне хороше рішення, хоча це, на мою думку, більше сумісне зі старими версіями Windows.
BuvinJ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.