Dormir en un archivo por lotes

151

Al escribir un archivo por lotes para automatizar algo en un cuadro de Windows, he tenido que pausar su ejecución durante varios segundos (generalmente en un ciclo de prueba / espera, esperando que se inicie un proceso). En ese momento, la mejor solución que pude encontrar utiliza ping (no es broma) para lograr el efecto deseado. He encontrado una mejor redacción aquí , que describe un "wait.bat" invocable, implementado de la siguiente manera:

@ping 127.0.0.1 -n 2 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul

Luego puede incluir llamadas a wait.bat en su propio archivo por lotes, pasando el número de segundos para dormir.

Aparentemente, el Kit de recursos de Windows 2003 proporciona un comando de suspensión similar a Unix (¡por fin!). Mientras tanto, para aquellos de nosotros que todavía usamos Windows XP, Windows 2000 o (lamentablemente) Windows NT , ¿hay una mejor manera?

Modifiqué el sleep.pyscript en la respuesta aceptada , de modo que su valor predeterminado sea un segundo si no se pasan argumentos en la línea de comando:

import time, sys

time.sleep(float(sys.argv[1]) if len(sys.argv) > 1 else 1)
Jason Etheridge
fuente
La página de descarga de Microsoft del Kit de recursos de Windows 2003 indica que también funciona para XP. Me temo que no hay otra opción que usar una utilidad 'externa' para hacer la espera: no hay nada como esto integrado en el procesador de comandos XP.
GerG
El kit de recursos del servidor 2003 funciona con Windows XP (y probablemente con w2k)
Martin Beckett
Enfrenté el mismo problema en el pasado y solía hacer ping a mí mismo (con un comentario anterior que documenta claramente que me doy cuenta de que esto es estúpido :)).
Jack Leow
2
Tiene un par de opciones: emule una suspensión con el pingcomando o descargue el kit de recursos de Windows que incluye un sleepcomando. Más detalles aquí: Archivo por lotes SLEEP Command
Rudu

Respuestas:

14

ACTUALIZAR

El timeoutcomando, disponible desde Windows Vista en adelante, debe ser el comando utilizado, como se describe en otra respuesta a esta pregunta. Lo que sigue aquí es una vieja respuesta.

Vieja respuesta

Si tiene instalado Python, o no le importa instalarlo (también tiene otros usos :), simplemente cree el siguiente script sleep.py y agréguelo en algún lugar de su RUTA:

import time, sys

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

Permitirá pausas de menos de un segundo (por ejemplo, 1.5 segundos, 0.1, etc.), en caso de que lo necesite. Si desea llamarlo como en sleeplugar de sleep.py, puede agregar la .PYextensión a su variable de entorno PATHEXT. En Windows XP, puede editarlo en:

Mi PC → Propiedades (menú) → Avanzado (pestaña) → Variables de entorno (botón) → Variables del sistema (marco)

tzot
fuente
32
¿por qué deberíamos escribir un script en python cuando se solicita una solución de procesamiento por lotes? ¿Cómo puede la extensión de ruta resolver el problema de que los usuarios de Windows no tienen instalado un intérprete de Python? Gracias.
Val
66
Por razones de portabilidad, creo que esta solución debería evitarse ya que existen alternativas nativas perfectamente buenas.
Gras Double
1
Este enfoque podría haber proporcionado una solución en el pasado, pero la solución nativa descrita por @Blorgbeard es definitivamente el camino a seguir.
Mike
227

El timeoutcomando está disponible desde Windows Vista en adelante:

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

Nota: no funciona con la redirección de entrada; ejemplo trivial:

C:\>echo 1 | timeout /t 1 /nobreak
ERROR: Input redirection is not supported, exiting the process immediately.
Blorgbeard está fuera
fuente
8
no funciona en usos sin consola: "ERROR: no se admite la redirección de entrada, saliendo del proceso de inmediato".
simpleuser
Me refiero a los casos en los que no tiene una consola en absoluto, como cuando el archivo por lotes se ejecuta en segundo plano a través de un tenedor de algún otro proceso, un crontab cygwin, o el comando ssh remoto, etc.
simpleuser
1
Oh si lo se El ejemplo que di fue solo para demostrar el error :)
Blorgbeard salió el
3
El enlace a la documentación para timeout, agregado por @Cristian Ciupitu, es parcialmente incorrecto: Windows XP no tiene este comando.
Martineau
1
@HelloWorld que suena como un problema con tu% PATH%
Blorgbeard sale el
21

Usar el pingmétodo como se describe es cómo lo hago cuando no puedo (o no quiero) agregar más ejecutables o instalar cualquier otro software.

Debería hacer ping a algo que no está allí, y usar la -wbandera para que falle después de ese período de tiempo, no hacer ping a algo que está allí (como localhost) -nveces. Esto le permite manejar el tiempo en menos de un segundo, y creo que es un poco más preciso.

p.ej

(prueba de que 1.1.1.1 no se toma)

ECHO Waiting 15 seconds

PING 1.1.1.1 -n 1 -w 15000 > NUL
  or
PING -n 15 -w 1000 127.1 >NUL
daniel
fuente
Regresa instantáneamente conPING: transmit failed. General failure.
huysentruitw
1.1.1.1CloudFlare toma la IP , por lo que no esperará 15 segundos sino alrededor de algunos ms.
dhcgn
16

SLEEP.exese incluye en la mayoría de los kits de recursos, por ejemplo, el Kit de recursos de Windows Server 2003 que también se puede instalar en Windows XP.

Usage:  sleep      time-to-sleep-in-seconds
        sleep [-m] time-to-sleep-in-milliseconds
        sleep [-c] commited-memory ratio (1%-100%)
Luk
fuente
15

No estoy de acuerdo con las respuestas que encontré aquí.

Utilizo el siguiente método completamente basado en las capacidades de Windows XP para retrasar un archivo por lotes:

RETARDO 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

También puede insertar el día en el cálculo para que el método también funcione cuando el intervalo de retraso pase más de la medianoche.

Aacini
fuente
15
Esto debería ser preciso, pero es una forma intensiva de CPU para hacerlo. Normalmente desea una implementación controlada por interrupción para que el proceso no consuma ciclos de CPU mientras espera. Esto no debería ser un problema para las esperas cortas infrecuentes, como probablemente sea el caso para la mayoría de las situaciones por lotes. Pero un proceso continuo con largas esperas podría tener un impacto negativo en el rendimiento del sistema.
dbenham
44
Como utiliza el reloj del sistema, la precisión es de un segundo. Si se especifican 2 segundos, el retraso puede ser entre 2 segundos y 3 segundos (en realidad 2.99999 ... segundos).
Peter Mortensen
¿Qué pasa si ahora son las 7:59:59 y quieres esperar 7 segundos? Parece que no tiene eso en cuenta.
cenizas999
Esto consume más tiempo de CPU del que cuenta el tiempo del sistema. Además, está realizando operaciones aritméticas con números octales, ya que los minutos y segundos menores que 10 se muestran con un 0 inicial en el TIMEcomando.
Andreas
2
@mrt: ¡El problema es que %TIME%usas una coma para separar los centisegundos, en lugar de un punto! Simplemente agregue una coma en DELIMS=:.,"...
Aacini
13

Me enfrenté a un problema similar, pero acabo de abrir una aplicación de consola C ++ muy corta para hacer lo mismo. Simplemente ejecute MySleep.exe 1000 , tal vez más fácil que descargar / instalar todo el kit de recursos.

#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;
}
John Sibly
fuente
10

En Server Fault, se hizo una pregunta similar y la solución fue:

choice /d y /t 5 > nul
mlsteeves
fuente
77
FYI: La opción no está incluida en Windows XP. Estaba en Windows 9x, se eliminó de XP y se volvió a agregar para Vista en adelante.
Devin Burke
77
No recomiendo esto en absoluto. Al menos en todas las CHOICEversiones que conozco, si alguien presiona un botón mientras espera, lo que a veces hacen las personas impacientes, entonces la opción registrará una entrada, emitirá un pitido del sistema por una entrada incorrecta y detendrá el temporizador de cuenta regresiva, lo que significa que se bloqueará allí a menos que presionen N o Y. Y si simplemente presionan uno de esos dos, entonces la elección termina allí en lugar de esperar a 5. Además, esta opción está usando una sintaxis de Vista realmente extraña. Todos los comandos de elección normales se usarían CHOICE /T:Y,5 > NULpara eso. No hay /Dbandera en las versiones anteriores.
Codificación con estilo
1
Para colmo, al menos los comandos CHOICE que conozco tienen diferentes botones sí / no predeterminados según el idioma en el que vino, por lo que si confía en una opción predeterminada [S, N] en lugar de especificarlo explícitamente con /C:YNo solo /C:Y, esto no funcionará cuando alguien tenga, por ejemplo, un comando de elección sueco que probablemente haga un [J, N] por defecto. Así que esto está sumido en todo tipo de problemas.
Codificación con estilo
1
@Coding Probó esto en Win7, y si el usuario presiona un botón, emitirá un pitido, sin embargo, seguirá expirando después de 5 segundos adicionales después de que el usuario presionó un botón. Entonces, si el usuario sigue presionando las teclas, nunca se agotará el tiempo de espera. Además, en mi caso, cuando usé esto, creo que oculta la consola, por lo que el usuario no puede presionar el botón. En este sistema, no había acceso a Python, no había acceso para dejar mi propio exe en el sistema (como se sugiere en algunas otras respuestas), estaba bastante limitado en lo que podía hacer. Entonces, ¿qué recomendarías?
mlsteeves
@mlsteeves Cada Windows, DOS, etc. diferente tiene un comando de elección diferente y, como se señaló, normalmente no está disponible en Xp. Muchos comandos de elección tienen un comportamiento sutilmente diferente y algunos incluso tienen una sintaxis diferente. Yo, generalmente uso el comando ping cuando necesito dormir. Es feo, pero confiable.
Codificación con estilo
9

Puede usar la capa WSH de cscript de Windows y este archivo JavaScript wait.js :

if (WScript.Arguments.Count() == 1)
    WScript.Sleep(WScript.Arguments(0)*1000);
else
    WScript.Echo("Usage: cscript wait.js seconds");
Blake7
fuente
1
Sin embargo, Windows Scripting Host se puede deshabilitar mediante políticas de grupo.
Joey
8

Dependiendo de sus necesidades de compatibilidad, use ping:

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

por ejemplo, esperar 5 segundos, usar

ping -n 6 localhost >nul 2>&1

o en Windows 7 o uso posterior timeout:

timeout 6 >nul
Joey
fuente
2
-westá en milisegundos, -nes el número de veces que se hace ping y el tiempo predeterminado entre pings es un segundo.
Joey
8

Puedes usar ping:

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

Esperará 10 segundos.

La razón por la que tiene que usar 11 es porque el primer ping se apaga inmediatamente, no después de un segundo. El número siempre debe ser uno más que la cantidad de segundos que desea esperar.

Tenga en cuenta que el propósito de la -wno es esperar un segundo. Es para asegurarse de que no espere más de un segundo en caso de que haya problemas de red. pingpor sí solo enviará un paquete ICMP por segundo. Probablemente no sea necesario para el host local, pero los viejos hábitos son difíciles.

paxdiablo
fuente
No se recomienda usar esto para el procesamiento crítico en tiempo real. Debido a que se está utilizando el comando PING, es posible que este archivo por lotes WAIT se ejecute durante unos pocos milisegundos
Wael Dalloul
12
@Wael, si estás hablando de esperar en límites de un segundo, unos pocos milisegundos serán irrelevantes. Y si estás usando cmd.exe para cosas en tiempo real, te mereces todo lo que obtienes :-)
paxdiablo
-w es un valor de tiempo de espera. Es el número de milisegundos que se espera una respuesta ... no la cantidad de tiempo que se espera entre pings.
quux
@quux, en ningún lugar dije que -wera el tiempo de espera (aunque admito que algunos pueden inferir que debido a mi falta de claridad), en realidad se usa para limitar el tiempo del ciclo donde hay problemas de red que causarían que cada ciclo tome más de lo asignado segundo. He agregado un párrafo al final para aclarar esto.
paxdiablo
El problema es que si los pings vuelven más rápido , no puede esperar un segundo completo entre pings. así que tu ciclo de espera terminará más rápido de lo que pensabas
quux
7

Hay una mejor manera de dormir usando ping. 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
Sí, esto es más fácil de escribir y comprender que tener que agregar uno al -nparámetro.
Peter Mortensen
Sin embargo, lo he medido (usando 100 pings). Si uso -n 3 -w 124, el tiempo real es exactamente (3 + 1) * (124 + 1) = 4 * 125 = 500 ms. El tiempo es sorprendentemente estable, exacto a la resolución de 10 ms en la lectura (por un aviso de CMD con tiempo), y la resolución subyacente es definitivamente mejor que 10 ms (no se ve afectada por la resolución habitual de tick de 16 ms).
Peter Mortensen
@mafu Que 192.0.2.0/24 no se debe usar no significa que no se pueda usar y, por lo tanto, no se garantiza realmente que no haya respuesta en la (s) solicitud (es) de eco. Por ejemplo, configure para cualquier PC con Windows la dirección IPv4 estática 192.0.2.1 y la máscara de subred 255.255.255.0 y conecte el adaptador de red a cualquier otro dispositivo. Un simple interruptor es suficiente en el que nada más está conectado. Luego, ejecute ping 192.0.2.1en esta PC con Windows y se puede ver que la pila TCP / IP de Windows responde a las solicitudes de eco. ¿Cuántas personas saben que 192.0.2.0/24 no debe usarse para una dirección IPv4 estática?
Mofi
1
Según la discusión en los comentarios aquí , parece que 192.0.2.1 no es tan infalible y algunos sugieren que 127.255.255.255 es una mejor opción. Pensamientos?
JLRishe
Los comentarios mencionados en la publicación anterior ahora se han eliminado (probablemente como NLN), pero estaría de acuerdo con el cambio 127.255.255.255debido a que es una dirección de bucle de difusión en Windows que ya está asignada de forma predeterminada (puede confirmar esto ejecutando route printen cmd y mirando a través de la tabla de rutas IPv4 que imprime).
Hoppeduppeanut
6

Si tiene PowerShell en su sistema, puede ejecutar este comando:

powershell -command "Start-Sleep -s 1"

Editar: a partir de mi respuesta en un hilo similar , las personas plantearon un problema en el que la cantidad de tiempo que toma PowerShell para comenzar es significativa en comparación con el tiempo que está tratando de esperar. Si la precisión del tiempo de espera es importante (es decir, un segundo o dos retrasos adicionales no son aceptables), puede utilizar este enfoque:

powershell -command "$sleepUntil = [DateTime]::Parse('%date% %time%').AddSeconds(5); $sleepDuration = $sleepUntil.Subtract((get-date)).TotalMilliseconds; start-sleep -m $sleepDuration"

Esto lleva el tiempo en que se emitió el comando de Windows, y el script de PowerShell duerme hasta 5 segundos después de ese tiempo. Por lo tanto, siempre que el PowerShell demore menos en iniciarse que la duración de su sueño, este enfoque funcionará (son alrededor de 600 ms en mi máquina).

Niall Connaughton
fuente
6
timeout /t <seconds> <options>

Por ejemplo, para hacer que el script realice una espera ininterrumpible de 2 segundos:

timeout /t 2 /nobreak >NUL

Lo que significa que el script esperará 2 segundos antes de continuar.

Por defecto, una pulsación de tecla interrumpirá el tiempo de espera, por lo tanto, use el /nobreakinterruptor si no desea que el usuario pueda interrumpir (cancelar) la espera. Además, el tiempo de espera proporcionará notificaciones por segundo para notificar al usuario cuánto tiempo le queda esperar; esto se puede eliminar canalizando el comando a NUL.

editar: como señala @martineau en los comentarios , el timeoutcomando solo está disponible en Windows 7 y versiones posteriores. Además, el pingcomando usa menos tiempo de procesador que timeout. Sin embargo, todavía creo en usarlo timeoutsiempre que sea posible, ya que es más legible que el ping'hack'. Lee más aquí .

mgthomas99
fuente
2
Aparentemente, este comando solo está disponible en Windows 7/2008 y el Kit de recursos de XP (y posiblemente 8 / 8.1). La fuente también afirma que el pingenfoque usa menos tiempo de procesador.
Martineau
5

Simplemente coloque esto en su archivo por lotes donde desea esperar.

@ping 127.0.0.1 -n 11 -w 1000 > null
Brent Stewart
fuente
¿Cómo es esto diferente de la respuesta de paxdiablo?
Peter Mortensen
2
No es diferente, pero las respuestas aquí provienen de múltiples preguntas combinadas, por lo que no todas las respuestas existieron cuando respondí.
Brent Stewart
4

En el Bloc de notas, escriba:

@echo off
set /a WAITTIME=%1+1
PING 127.0.0.1 -n %WAITTIME% > nul
goto:eof

Ahora guárdelo como wait.bat en la carpeta C: \ WINDOWS \ System32, luego, cuando quiera esperar, use:

CALL WAIT.bat <whole number of seconds without quotes>
SuperKael
fuente
Se hace sonar repetidamente, esperando un segundo entre cada ping, y luego vuelve al programa de llamada, no veo el bucle infinito, pero lo he probado yo mismo.
SuperKael
Mi error, no hay bucle infinito. Sin embargo, como se menciona en una de las otras respuestas , es mejor hacer pingalgo no solo una vez, y usar la -w Timeoutopción para el tiempo de retraso en milisegundos en lugar de la -n Countopción de número total de reintentos.
Martineau
-w Timeoutpuede ser mejor, pero me aseguré de que suene una vez más que la hora ingresada.
SuperKael
4

El Kit de recursos siempre ha incluido esto. Al menos desde Windows 2000.

¡Además, el paquete Cygwin tiene un sleep- plop que en su RUTA e incluye cygwin.dll(o como se llame) y el camino a seguir!

Daren Thomas
fuente
2
Tenga en cuenta que cygwin1.dll no coexiste pacíficamente con diferentes versiones de sí mismo. Es mejor que tenga uno y solo un cygwin1.dll en su máquina, o obtendrá fallas extrañas.
JesperE
¿Qué kit de recursos? Parece que hay más de uno. ¿Puedes actualizar tu respuesta?
Peter Mortensen
3

Me gusta la respuesta de Aacini . Le agregué para manejar el día y también habilitarlo para manejar centisegundos ( %TIME%salidas 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
fuente
3

He estado usando este programa de sueño C #. Puede ser más conveniente para usted si C # es su idioma preferido:

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
fuente
3

Aún más liviano que la solución Python es un Perl one-liner.

Para dormir durante siete segundos ponga esto en el script BAT:

perl -e "sleep 7"

Esta solución solo proporciona una resolución de un segundo.

Si necesita una resolución más alta, use el módulo Time :: HiRes de CPAN. Proporciona usleep()qué duerme en microsegundos y nanosleep()qué duerme en nanosegundos (ambas funciones toman solo argumentos enteros). Ver la pregunta de desbordamiento de pila ¿ Cómo duermo un milisegundo en Perl? para mas detalles.

He usado ActivePerl por muchos años. Es muy fácil de instalar.

Peter Mortensen
fuente
2

O línea de comando Python, por ejemplo, durante 6 segundos y medio:

python -c "import time;time.sleep(6.5)"
Alex Robinson
fuente
Aunque más corto, este es un duplicado de la respuesta aceptada.
Peter Mortensen
@ Peter Mortensen: también le permite poner todo fácilmente en una sola línea de un archivo por lotes.
Martineau
2

El uso de ping es bueno, siempre y cuando solo quieras "esperar un poco". Esto ya que depende de otras funciones debajo, como el funcionamiento de su red y el hecho de que no hay nada que responda en 127.0.0.1. ;-) Tal vez no sea muy probable que falle, pero no es imposible ...

Si desea asegurarse de que está esperando exactamente el tiempo especificado, debe usar el sleep funcionalidad (que también tiene la ventaja de que no usa la potencia de la CPU o espera a que una red esté lista).

Encontrar un ejecutable ya hecho para dormir es la forma más conveniente. Simplemente colóquelo en su carpeta de Windows o en cualquier otra parte de su ruta estándar y siempre estará disponible.

De lo contrario, si tiene un entorno de compilación, puede hacer uno fácilmente. La Sleepfunción está disponible en kernel32.dll, por lo que solo necesita usar esa. :-) Para VB / VBA declare lo siguiente al comienzo de su fuente para declarar una función de suspensión:

private Declare Sub Sleep Lib "kernel32" Alias "Sleep" (byval dwMilliseconds as Long)

Para C #:

[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);

Aquí encontrará más información sobre esta funcionalidad (disponible desde Windows 2000) en la función Suspender (MSDN).

En el estándar C, sleep()se incluye en la biblioteca estándar y en Visual Studio C de Microsoft se nombra la función Sleep(), si la memoria me sirve. ;-) Esos dos toman el argumento en segundos, no en milisegundos como las dos declaraciones anteriores.

Tooony
fuente
1
El modo de suspensión está disponible en el marco .net: eche un vistazo a la clase de subproceso, por ejemplo: usar System.Threading; .... Hilo. Dormir (1000);
John Sibly
2
Si "ping 127.0.0.1" falla, tiene que preocuparse de cosas más serias que "dormir": esta es la interfaz de bucle invertido, cualquier cosa que RPC probablemente se vuelva loco.
Piskvor salió del edificio el
2

La mejor solución que debería funcionar en todas las versiones de Windows después de Windows 2000 sería:

timeout numbersofseconds /nobreak > nul
Tato
fuente
No funciona en XP Pro ...'timeout' is not recognized as an internal or external command, operable program or batch file.
Martineau
1

El pathping.exe puede dormir menos de un segundo.

@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
fuente
1

Estoy impresionado con este:

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

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

Técnicamente, le estás diciendo al choicecomando que acepte solo y. Su valor predeterminado es y, hacerlo en 5 segundos, no dibujar ningún aviso y volcar todo lo que le dice a NUL (como un terminal nulo en Linux).

Chris Moschini
fuente
3
Me repetiré aquí: no lo recomiendo en absoluto. En las CHOICEversiones que conozco, si alguien presiona una tecla mientras espera, lo que a veces hacen las personas impacientes, entonces la opción leerá una entrada, emitirá un pitido del sistema por una entrada incorrecta y detendrá la cuenta regresiva, por lo que se bloqueará a menos que presione Y. Y si simplemente presionan Y, entonces la elección termina allí en lugar de esperar a 5. Además, esta opción está usando una sintaxis de Vista realmente extraña. Los comandos de elección normal en su lugar se utilizan CHOICE /T:Y,5 > NULpara eso. (No hay bandera / D en las versiones anteriores). Y si tiene Vista, TIMEOUTúsela.
Codificación con estilo
1

También puede usar un archivo .vbs para hacer tiempos de espera específicos:

El siguiente código crea el archivo .vbs. Pon esto cerca de la parte superior de tu código de lote:

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

El siguiente código abre el archivo .vbs y especifica cuánto tiempo esperar:

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

En el código anterior, el "1000" es el valor del retraso de tiempo que se enviará al archivo .vbs en milisegundos, por ejemplo, 1000 ms = 1 s. Puede modificar esta parte para que sea lo largo que desee.

El siguiente código elimina el archivo .vbs después de que haya terminado con él. Ponga esto al final de su archivo por lotes:

del /f /q "%cd%\sleeper.vbs"

Y aquí está todo el código, así que es fácil de copiar:

echo WScript.sleep WScript.Arguments(0) >"%cd%\sleeper.vbs"
start /WAIT "" "%cd%\sleeper.vbs" "1000"
del /f /q "%cd%\sleeper.vbs"
EpicNinjaQueso
fuente
1

Desde Windows Vista en adelante, tiene los comandos TIMEOUT y SLEEP , pero para usarlos en Windows XP o Windows Server 2003, necesitará el kit de herramientas de recursos de Windows Server 2003 .

Aquí tiene una buena visión general de las alternativas de suspensión (el enfoque de ping es el más popular, ya que funcionará en todas las máquinas con Windows), pero hay (al menos) una que no se menciona que (ab) usa el W32TMcomando (Servicio de tiempo):

w32tm /stripchart /computer:localhost /period:1 /dataonly /samples:N  >nul 2>&1

Donde debe reemplazar la N con los segundos que desea pausar. Además, funcionará en todos los sistemas Windows sin requisitos previos.

Typeperf también se puede usar:

typeperf "\System\Processor Queue Length" -si N -sc 1 >nul

Con mshta y javascript (se puede usar para dormir menos de un segundo):

start "" /wait /min /realtime mshta "javascript:setTimeout(function(){close();},5000)"

Esto debería ser aún más preciso (para esperar menos de un segundo): el ejecutable de compilación automática depende de .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
fuente
1

Hay muchas formas de lograr un ' sueño ' en cmd / lote:

Mi favorito:

TIMEOUT /NOBREAK 5 >NUL 2>NUL

Esto detendrá la consola durante 5 segundos, sin ninguna salida.

Más usado:

ping localhost -n 5 >NUL 2>NUL

Esto intentará hacer una conexión localhost5 veces. Como está alojado en su computadora, siempre llegará al host, por lo que cada segundo probará lo nuevo cada segundo. La -nbandera indica cuántas veces el script intentará la conexión. En este caso es 5, por lo que durará 5 segundos.

Variantes de la última:

ping 1.1.1.1 -n 5 >nul

En este script hay algunas diferencias comparándolo con el último. Esto no intentará llamar localhost. En cambio, intentará conectarse a 1.1.1.1un sitio web muy rápido. La acción durará 5 segundos solo si tiene una conexión a Internet activa. De lo contrario, durará aproximadamente 15 para completar la acción . No recomiendo usar este método.

ping 127.0.0.1 -n 5 >nul

Esto es exactamente lo mismo que en el ejemplo 2 (el más utilizado). Además, también puedes usar:

ping [::1] -n 5 >nul

Esto, en cambio, usa la localhostversión de IPv6 .

Hay muchos métodos para realizar esta acción. Sin embargo, prefiero el método 1 para Windows Vista y versiones posteriores y el método más utilizado (método 2) para versiones anteriores del sistema operativo.

Lumito
fuente
0

Puedes ponerte elegante poniendo el mensaje PAUSE en la barra de título:

@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
fuente
0

Esto se probó en Windows XP SP3 y Windows 7 y utiliza CScript. Me puse algunas medidas de seguridad para evitar la "" incitación. ( /qsería peligroso)

Espera un segundo:

sleepOrDelayExecution 1000

Espere 500 ms y luego ejecute cosas después de:

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
Cobarde anónimo
fuente
0

Como otros sugieren programas de terceros (Python, Perl, aplicaciones personalizadas, etc.), otra opción es GNU CoreUtils para Windows disponible en http://gnuwin32.sourceforge.net/packages/coreutils.htm .

2 opciones para la implementación:

  1. Instale el paquete completo (que incluirá el conjunto completo de CoreUtils, dependencias, documentación, etc.).
  2. Instale solo las dependencias binarias y necesarias de 'sleep.exe' (use depe.exe para obtener dependencias).

Una ventaja de implementar CoreUtils es que además obtendrá una gran cantidad de otros programas que son útiles para la creación de scripts (el lote de Windows deja mucho que desear).

codeniffer
fuente