¿Cómo dormir en un archivo por lotes?

132

¿Cómo pausar la ejecución durante un tiempo en un archivo por lotes de Windows entre un comando y el siguiente?

Massimo
fuente
¿Está destinado a convertirse en un canónico? Si es así, podría ser apropiado algún texto explicativo.
John Gardeniers
2
¿"Texto explicativo" como en?
Massimo
2
La mayoría, si no todas, las preguntas canónicas que he visto incluyen texto que describe la intención de esa pregunta.
John Gardeniers
O algún texto que explique la situación ... Es principalmente para ayudar con SEO, pero también ayuda a enmarcar posibles respuestas.
Chris S
2
SEO funciona bien. Primer golpe para mí en la búsqueda de Google.
jbo5112

Respuestas:

194

La forma correcta de dormir en un archivo por lotes es usar el timeoutcomando, introducido en Windows 2000.

Para esperar entre 29 y 30 segundos :

timeout /t 30

El tiempo de espera se interrumpiría si el usuario presiona cualquier tecla; sin embargo, el comando también acepta el interruptor opcional /nobreak, que ignora efectivamente cualquier cosa que el usuario pueda presionar, excepto un explícito CTRL-C:

timeout /t 30 /nobreak

Además, si no desea que el comando imprima su cuenta regresiva en la pantalla, puede redirigir su salida a NUL:

timeout /t 30 /nobreak > NUL
Massimo
fuente
66
El comando de tiempo de espera no funciona con Windows XP, incluso con el kit de recursos 2003 instalado y el comando de suspensión no funciona en Windows 7, por lo que el comando ping puede ser útil si está utilizando el archivo por lotes en Win7 y WinXP.
12
el tiempo de espera no funciona en secuencias de comandos no interactivas: "ERROR: no se admite la redirección de entrada, que sale del proceso inmediatamente". así que a veces se prefiere usar hack con "ping"
iMysak
14

Como también se aplica aquí, copiaré mi respuesta de otro sitio .

Si quieres usar ping, hay una mejor manera. Querrá hacer ping a una dirección que no existe, por lo que puede especificar un tiempo de espera con precisión de milisegundos. Afortunadamente, dicha dirección se define en un estándar (RFC 3330), y lo es 192.0.2.x. Esto no está inventado, realmente es una dirección con el único propósito de no existir (puede que no esté claro, pero se aplica incluso en redes locales):

192.0.2.0/24: este bloque se asigna como "TEST-NET" para su uso en documentación y código de ejemplo. A menudo se usa junto con los nombres de dominio example.com o example.net en la documentación del proveedor y del protocolo. Las direcciones dentro de este bloque no deben aparecer en Internet pública.

Para dormir 123 milisegundos, use ping 192.0.2.1 -n 1 -w 123 >nul

mafu
fuente
3
No haga eso, incluso si es un poco mejor que hacer ping a una dirección real. Pinges simplemente la herramienta incorrecta para el trabajo.
Massimo
1
@Massimo Lo más probable es que no sea lo que se pretendía hacer :) Pero creo que es una buena solución, funciona mejor que el tiempo de espera en algunos escenarios (en particular, una resolución más alta). Además, se ha vuelto bastante conocido, por lo que la mayoría de las personas no se sorprenderán mucho (es decir, estarán confundidas) cuando lo vean en su archivo por lotes.
mafu
2
@Massimo ¡Muy bien! Supongo que solo tenemos diferentes puntos de vista. Si no le importa, aún dejaré esta respuesta, ya que parece ser mejor que hacer ping localhost n veces como se describe con mayor frecuencia.
mafu 18/0714
77
timeout es la solución adecuada para los sistemas operativos en los que trabaja. ping es la única solución que funciona desde 5.1-6.3. Con el 25% de los sistemas todavía en 5.1, el tiempo de espera no es "la forma correcta".
Wyrmwood
3
timeout es la solución incorrecta para cualquier sistema operativo, porque está fatalmente roto incluso en Windows 10. ¿De qué sirve un comando que falla solo porque la entrada se redirige?
Harry Johnston
8

También puede insertar un ping a localhost. Esto tardará 4 segundos en completarse (de forma predeterminada). Algunos lo consideran un error, pero de todos modos funciona bastante bien.

El comando:
ping 127.0.0.1

acólito
fuente
66
Ehm ... todo el propósito de este Q / A era exactamente corregir otras dos preguntas que tienen esto como su respuesta aceptada, pero ya no se pueden corregir porque su OP ya no está disponible.
Massimo
66
Si bien funcionará, es el equivalente a clavar un tornillo con un martillo. Una herramienta incorrecta puede funcionar, pero sigue siendo incorrecta.
voretaq7
1
@ MarkAllen En otras palabras, ¿Windows NT4, 95, 98, ME y anteriores?
Chris McKeown
55
@ MarkAllen: técnicamente, debe preocuparse por si pingviene con su sistema operativo o no . Si te preocupa lo suficiente sobre '95 '98 o ME, entonces debería ser igualmente preocupado por 6,22 que no tiene pingo bien
Mark Henderson
44
@ MarkHenderson Es más fácil (para mí) recordar si una versión particular del sistema operativo es compatible con TCP / IP que recordar si incluye o no un comando que no había escuchado anteriormente. ¿Ya sabes?
Mark Allen
2

Descargo de responsabilidad : esta no es la solución "ideal", así que no te molestes en golpearme la cabeza con eso como lo hicieron los que recomiendan ping...

Cuando sea posible, úselo timeoutcon seguridad. Pero como se señaló en los comentarios, esa no siempre es una opción (por ejemplo, en modo no interactivo). Después de eso, estoy de acuerdo en que ping"kludge" es quizás la siguiente mejor opción, ya que es muy simple. Dicho esto, ofrezco otra opción ... incrustar algunos VB Script .

La base de esta solución tiene todo tipo de aplicaciones más allá de esto. A menudo, VBS puede hacer cosas que el lote no puede, o al menos hacerlo con mucha más facilidad. Usando la técnica ilustrada aquí, puede mezclar los dos (no "sin problemas", sino "funcionalmente" ...).

Aquí hay un trazador de líneas, para crear un script temporal, ejecutarlo y luego eliminarlo. El script duerme por ti (durante 3 segundos en este ejemplo).

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

Esto es básicamente lo mismo, escrito de manera un poco diferente:

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

Y, por último, al igual que ping, CScripten sí tiene una opción de tiempo de espera! Entonces, si ingresa un bucle infinito en el script, puede dejar que el intérprete imponga la duración. Tenga en cuenta que esta es una operación "ocupada", que consume la CPU y, por lo tanto, no la recomiendo cuando puede usar el WScript.Sleepprocedimiento, pero lo presento como una opción conceptual en aras de la integridad:

set sleepSec=3 & set sleepVbs=%temp%\sleep.vbs & echo While True > %sleepVbs% & echo Wend >> %sleepVbs% & cscript %sleepVbs% //B //T:%sleepSec% & del %sleepVbs%
BuvinJ
fuente
Sabes ... podrías hacer esto en PowerShell, espero, sin tener que escribir un archivo.
Harry Johnston
Sí, es probable que sea otra buena solución, aunque creo que esta es más compatible con versiones anteriores de Windows.
BuvinJ