python batch-file

python - Dormir en un archivo por lotes



batch-file (29)

Aún más ligero que la solución Python es un Perl de una sola línea.

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

perl -e "sleep 7"

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

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

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

Al escribir un archivo por lotes para automatizar algo en un cuadro de Windows, tuve 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 usa ping (no es broma) para lograr el efecto deseado. Encontré una mejor descripción here , 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 la cantidad de segundos para dormir.

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

sleep.py script sleep.py en la respuesta aceptada , por lo que se establece de manera predeterminada en 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)


Dependiendo de tus necesidades de compatibilidad, usa 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 posterior use timeout :

timeout 6 >nul


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

Here 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 de Windows), pero hay (al menos) uno que no menciona que (ab) usa el W32TM (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 de Windows sin requisitos previos.

Typeperf también se puede usar:

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


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

Además, el paquete Cygwin tiene una función de sleep que ingresa en su PATH e incluye el cygwin.dll (o como se llame) ¡y el camino a seguir!


El comando de timeout 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.


El pathping.exe puede dormir menos que el 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


El uso del ping es bueno, siempre y cuando solo quieras "esperar un poco". Esto ya que depende de otras funciones debajo, como la red trabajando 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 quiere estar seguro de que está esperando exactamente el tiempo especificado, debe usar la función de sleep (que también tiene la ventaja de que no usa la potencia de la CPU o espera a que la 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 crear uno usted mismo. La función Sleep está disponible en kernel32.dll , por lo que solo necesita usar esa. :-) Para VB / VBA, declare lo siguiente al principio 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 de Suspensión (MSDN).

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



En el Bloc de notas, escribe:

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


Esto se probó en Windows XP SP3 y Windows 7 y usa CScript. Puse algunos protectores seguros para evitar "" indicaciones del del. ( /q serí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


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 comando de choice que acepte solo y. Por defecto es y, para hacerlo en 5 segundos, para no dibujar ningún aviso, y para volcar cualquier cosa que diga a NUL (como terminal nulo en Linux).


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 una precisión de milisegundos. Afortunadamente, dicha dirección se define en un estándar (RFC 3330) y es 192.0.2.x Esto no está inventado, realmente es una dirección con el único propósito de no existir (puede no ser 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 deberían aparecer en Internet público.

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


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


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


Me enfrenté a un problema similar, pero acabo de derribar una aplicación de consola C ++ muy corta para hacer lo mismo. Simplemente ejecute MySleep.exe 1000 , quizás 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; }


Me gusta la respuesta de Aacini . centiseconds para manejar el día y también para manejar centiseconds ( %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


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:

DELAY.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 demora pase la medianoche.


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

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


Puede hacerse elegante poniendo el mensaje PAUSA 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


Puede usar la capa WSH de Windows cscript 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");


Puedes usar ping:

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

Esperará 10 segundos.

La razón por la que debe 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 el número de segundos que desea esperar.

Tenga en cuenta que el objetivo de -w no es esperar un segundo. Es para garantizar que no espere más de un segundo en caso de que haya problemas de red. ping por sí mismo enviará un paquete ICMP por segundo. Probablemente no sea necesario para el host local, pero los viejos hábitos son difíciles.


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 , la gente planteó un problema en el que la cantidad de tiempo que toma PowerShell para comenzar es significativo 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 toma el tiempo cuando se emitió el comando de Windows y el script de powershell duerme hasta 5 segundos después de ese momento. Así que mientras Powershell tome menos tiempo para comenzar que la duración de su sueño, este enfoque funcionará (está a unos 600 ms en mi máquina).


Si tiene Python instalado, 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 por debajo del segundo (por ejemplo, 1.5 segundos, 0.1, etc.), si así lo necesita. Si desea llamarlo como sleep lugar de sleep.py , puede agregar la extensión .PY 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)


Simplemente coloque esto en su archivo por lotes donde desea la espera.

@ping 127.0.0.1 -n 11 -w 1000 > null


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

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

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

El código a continuación abre el .vbs y especifica cuánto tiempo esperar:

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

En el código anterior, el "1000" es el valor de la demora de tiempo que se enviará al archivo .vbs en milisegundos, por ejemplo, 1000 ms = 1 s. Puedes modificar esta parte por el tiempo que quieras.

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

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

Y aquí está el código todo junto, 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"


Usar el método ping 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 el -w para que falle después de esa cantidad de tiempo, sin hacer ping a algo que está allí (como localhost) -n veces. Esto le permite manejar 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


SLEEP.exe se 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%)


ping -n X 127.0.0.1 > nul

Reemplace X con la cantidad de segundos + 1.

Por ejemplo, si tuviera que esperar 10 segundos, reemplace X con 11. Para esperar 5 segundos, use 6.

Lea respuestas anteriores por milisegundos.


timeout /t <seconds> <options>

Por ejemplo, para que el script realice una espera de 2 segundos no ininterrumpida:

timeout /t 2 /nobreak >NUL

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

De forma predeterminada, una pulsación de tecla interrumpirá el tiempo de espera, por lo tanto, utilice el /nobreak 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 queda esperar; esto se puede eliminar conectando el comando a NUL .

editar: como señala martineau en los comentarios , el comando de timeout solo está disponible en Windows 7 y superior. Además, el comando ping usa menos tiempo de procesador que timeout . Todavía creo en el uso del timeout siempre que sea posible, ya que es más legible que el ping ''hack''. Lea más here .