Dormire in un file batch


150

Quando scrivo un file batch per automatizzare qualcosa su una finestra di Windows, ho bisogno di sospenderne l'esecuzione per alcuni secondi (di solito in un ciclo di test / attesa, in attesa dell'avvio di un processo). Al momento, la migliore soluzione che ho potuto trovare utilizza il ping (non ti scherzo) per ottenere l'effetto desiderato. Ho trovato una migliore scrittura di questo qui , che descrive un callable "wait.bat", implementato come segue:

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

È quindi possibile includere le chiamate a wait.bat nel proprio file batch, passando il numero di secondi di sospensione.

Apparentemente il Resource Kit di Windows 2003 fornisce un comando di sospensione simile a Unix (finalmente!). Nel frattempo, per quelli di noi che usano ancora Windows XP, Windows 2000 o (purtroppo) Windows NT , c'è un modo migliore?

Ho modificato lo sleep.pyscript nella risposta accettata , in modo che sia impostato per impostazione predefinita su un secondo se non viene passato alcun argomento sulla riga di comando:

import time, sys

time.sleep(float(sys.argv[1]) if len(sys.argv) > 1 else 1)

La pagina di download di Microsoft del Resource Kit di Windows 2003 indica che funziona anche con XP. Temo che non ci sia altra scelta se non quella di utilizzare un'utilità "esterna" per fare l'attesa: non c'è nulla di simile incorporato nel processore dei comandi di XP.
GerG,

Il kit di risorse del server 2003 funziona con Windows XP (e probabilmente con w2k)
Martin Beckett,

Ho affrontato lo stesso problema in passato e ho usato il ping da solo (con un'osservazione sopra che documenta chiaramente che mi rendo conto che questo è stupido :)).
Jack Leow,


2
Hai un paio di opzioni: emula una sospensione con il pingcomando o scarica il kit di risorse di Windows che include un sleepcomando. Maggiori dettagli qui: File batch Comando SLEEP
Rudu

Risposte:


14

AGGIORNARE

Il timeoutcomando, disponibile da Windows Vista e successivi, dovrebbe essere il comando utilizzato, come descritto in un'altra risposta a questa domanda. Quello che segue qui è un vecchio risposta.

Vecchia risposta

Se hai installato Python o non ti dispiace installarlo (ha anche altri usi :), crea il seguente script sleep.py e aggiungilo da qualche parte nel tuo PERCORSO:

import time, sys

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

Consentirà pause al secondo secondo (ad esempio, 1,5 sec, 0,1, ecc.), Nel caso in cui ne abbiate bisogno. Se si desidera chiamarlo come sleepanziché anziché sleep.py, è possibile aggiungere il.PY estensione alla variabile di ambiente PATHEXT. Su Windows XP, puoi modificarlo in:

Risorse del computer → Proprietà (menu) → Avanzate (scheda) → Variabili d'ambiente (pulsante) → Variabili di sistema (frame)


32
perché dovremmo scrivere uno script in Python quando è richiesta una soluzione batch-scriptabile? In che modo l'estensione del percorso può risolvere il problema per cui gli utenti di Windows non hanno alcun interprete Python installato? Grazie.
Val

6
Per motivi di portabilità, penso che questa soluzione dovrebbe essere evitata in quanto esistono alternative native perfettamente perfette.
Gras Double

1
Questo approccio potrebbe aver fornito una soluzione alternativa in passato, ma la soluzione nativa descritta da @Blorgbeard è sicuramente la strada da percorrere.
Mike

227

Il timeoutcomando è disponibile da Windows Vista in poi:

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: non funziona con il reindirizzamento dell'input - esempio banale:

C:\>echo 1 | timeout /t 1 /nobreak
ERROR: Input redirection is not supported, exiting the process immediately.

8
non funziona negli usi senza console: "ERRORE: reindirizzamento input non supportato, uscendo immediatamente dal processo".
simpleuser

Intendevo casi in cui non hai affatto una console, ad esempio quando il file batch viene eseguito in background tramite un fork da un altro processo, un crontab cygwin o un comando ssh remoto, ecc.
simpleuser

1
Oh sì, lo so. L'esempio che ho fatto è stato solo per dimostrare l'errore :)
Blorgbeard è uscito il

3
Il collegamento alla documentazione per timeout, aggiunto da @Cristian Ciupitu, è parzialmente errato - Windows XP non ha questo comando.
martineau,

1
@HelloWorld che sembra un problema con il tuo% PATH%
Blorgbeard uscirà il

21

L'uso del pingmetodo come indicato è come lo faccio quando non riesco (o non voglio) aggiungere altri eseguibili o installare altri software.

Dovresti eseguire il ping di qualcosa che non è presente e utilizzare il -wflag in modo che non riesca dopo quel lasso di tempo, non eseguire il ping di qualcosa che è lì (come localhost) -nvolte. Ciò ti consente di gestire il tempo in meno di un secondo e penso che sia leggermente più preciso.

per esempio

(prova che 1.1.1.1 non viene preso)

ECHO Waiting 15 seconds

PING 1.1.1.1 -n 1 -w 15000 > NUL
  or
PING -n 15 -w 1000 127.1 >NUL

Ritorna istantaneamente conPING: transmit failed. General failure.
huysentruitw

L'IP 1.1.1.1viene utilizzato da CloudFlare, quindi questo non attenderà 15 secondi ma circa alcuni ms.
dhcgn il

16

SLEEP.exeè incluso nella maggior parte dei kit di risorse, ad esempio il Resource Kit di Windows Server 2003 che può essere installato anche su Windows XP.

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

15

Non sono d'accordo con le risposte che ho trovato qui.

Uso il seguente metodo interamente basato sulle funzionalità di Windows XP per ritardare un file batch:

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

È inoltre possibile inserire il giorno nel calcolo in modo che il metodo funzioni anche quando l'intervallo di ritardo supera la mezzanotte.


15
Questo dovrebbe essere accurato, ma è un modo intensivo della CPU per farlo. Normalmente si desidera un'implementazione guidata dall'interrupt in modo che il processo non consumi i cicli della CPU mentre attende. Questo non dovrebbe essere un problema per le brevi attese rare, come è probabilmente il caso della maggior parte delle situazioni batch. Ma un processo continuo con lunghe attese potrebbe avere un impatto negativo sulle prestazioni del sistema.
dbenham,

4
Poiché utilizza l'orologio di sistema, la precisione è di un secondo. Se vengono specificati 2 secondi, il ritardo può essere compreso tra 2 secondi e 3 secondi (in realtà 2,99999 ... secondi).
Peter Mortensen,

Che cosa succede se adesso sono le 7:59:59 e vuoi aspettare 7 secondi? Sembra che non ne tenga conto.
ashes999,

Ciò consuma più tempo della CPU di quanto conta il tempo di sistema. Inoltre, si stanno eseguendo operazioni aritmetiche con numeri ottali, poiché minuti e secondi inferiori a 10 vengono visualizzati con uno 0 iniziale nel TIMEcomando.
Andreas

2
@mrt: il problema è che %TIME%usi una virgola per separare i centisecondi, anziché un punto! Basta aggiungere una virgola in DELIMS=:.,"...
Aacini,

13

Ho riscontrato un problema simile, ma ho appena rovinato un'applicazione console C ++ molto corta per fare la stessa cosa. Basta eseguire MySleep.exe 1000 , forse più semplice del download / installazione dell'intero kit di risorse.

#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;
}

10

A Server Fault, è stata posta una domanda simile e la soluzione era:

choice /d y /t 5 > nul

7
Cordiali saluti: la scelta non è inclusa in Windows XP. Era in Windows 9x, rimosso da XP e aggiunto nuovamente per Vista.
Devin Burke,

7
Non lo consiglio affatto. Almeno in tutte le CHOICEversioni che conosco, se qualcuno preme un pulsante durante l'attesa, cosa che a volte fanno persone impazienti, la scelta registrerà un input, emetterà un segnale acustico di sistema per un input errato e fermerà il timer per il conto alla rovescia, il che significa che si bloccherà lì a meno che non spingano N o Y. E se capita semplicemente di spingere uno di quei due, allora la scelta finisce lì invece di aspettare 5. Inoltre, questa scelta sta usando una sintassi Vista davvero strana. Tutti i normali comandi di scelta userebbero invece CHOICE /T:Y,5 > NULper quello. Non c'è /Dbandiera nelle vecchie versioni.
Coding With Style

1
Per finire, almeno i comandi CHOICE che conosco hanno diversi pulsanti sì / no predefiniti in base alla lingua in cui è arrivato, quindi se ti capita di fare affidamento su una scelta [Y, N] predefinita invece di specificarla esplicitamente con /C:YNo solo /C:Y, questo non funzionerà quando qualcuno avrà, per esempio, un comando di scelta svedese che probabilmente eseguirà un [J, N] di default. Quindi questo è impantanato in tutti i tipi di problemi.
Coding With Style

1
@Coding Testato in Win7 e se l'utente preme un pulsante, emetterà un segnale acustico, tuttavia continuerà a scadere dopo altri 5 secondi dopo che l'utente ha premuto un pulsante. Quindi, se l'utente continua a premere i tasti, non scadrà mai. Inoltre, nel mio caso, quando l'ho usato, credo che nasconda la console, in modo che l'utente non possa premere il pulsante. Su questo sistema, non c'era accesso a Python, non c'era accesso per eliminare il mio exe sul sistema (come suggerito in altre risposte), ero piuttosto limitato in ciò che potevo fare. Quindi, cosa consiglieresti?
mlsteeves,

@mlsteeves Ogni diverso Windows, DOS, ecc. ha un comando di scelta diverso e, come notato, normalmente non è disponibile in Xp. Molti comandi di scelta hanno comportamenti leggermente diversi e alcuni hanno persino una sintassi diversa. Io, generalmente utilizzo il comando ping quando ho bisogno di dormire. È brutto, ma affidabile.
Coding With Style

9

È possibile utilizzare il livello WSH cscript di Windows e questo file JavaScript wait.js :

if (WScript.Arguments.Count() == 1)
    WScript.Sleep(WScript.Arguments(0)*1000);
else
    WScript.Echo("Usage: cscript wait.js seconds");

1
Tuttavia, l'host di script di Windows può essere disabilitato tramite criteri di gruppo.
Joey,

8

A seconda delle esigenze di compatibilità, utilizzare ping:

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

ad es. per attendere 5 secondi, utilizzare

ping -n 6 localhost >nul 2>&1

o su Windows 7 o versioni successive utilizzare timeout:

timeout 6 >nul

2
-wè espresso in millisecondi, -nè solo il numero di volte in cui eseguire il ping e il tempo predefinito tra i ping è un secondo.
Joey,

8

Puoi usare il ping:

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

Aspetterà 10 secondi.

Il motivo per cui devi usare 11 è perché il primo ping si spegne immediatamente, non dopo un secondo. Il numero dovrebbe essere sempre uno in più del numero di secondi che si desidera attendere.

Tieni presente che lo scopo del -wnon è di aspettare un secondo. È per garantire che non si attenda più di un secondo nel caso in cui ci siano problemi di rete. pingda solo invierà un pacchetto ICMP al secondo. Probabilmente non è richiesto per localhost, ma le vecchie abitudini sono dure a morire.


non è consigliabile utilizzarlo per l'elaborazione critica in tempo reale. poiché viene utilizzato il comando PING, è possibile che questo file batch WAIT possa essere eseguito per alcuni millisecondi
Wael Dalloul,

12
@Wael, se stai parlando di aspettare sui confini di un secondo, qualche millisecondo sarà irrilevante. E se stai usando cmd.exe per cose in tempo reale, ti meriti tutto ciò che ottieni :-)
paxdiablo

-w è un valore di timeout. È il numero di millisecondi di attesa per una risposta ... non il tempo di attesa tra ping.
quux,

@quux, da nessuna parte ho affermato che -wil timeout (anche se ammetto che alcuni potrebbero dedurlo a causa della mia mancanza di chiarezza), è effettivamente utilizzato per limitare il tempo di ciclo in cui ci sono problemi di rete che causerebbero a ciascun ciclo di prendere più del previsto secondo. Ho aggiunto un paragrafo alla fine per chiarire questo.
paxdiablo,

il problema è che se i ping tornano più velocemente , non si può attendere un secondo intero tra i ping. quindi il tuo ciclo di attesa finirà più velocemente di quanto pensassi
quux

7

C'è un modo migliore per dormire usando il ping. Ti consigliamo di eseguire il ping di un indirizzo che non esiste, quindi puoi specificare un timeout con precisione in millisecondi. Fortunatamente, un tale indirizzo è definito in uno standard (RFC 3330), e lo è 192.0.2.x. Questo non è inventato, è davvero un indirizzo al solo scopo di non esistere (potrebbe non essere chiaro, ma si applica anche nelle reti locali):

192.0.2.0/24 - Questo blocco è assegnato come "TEST-NET" per l'uso nella documentazione e nel codice di esempio. Viene spesso utilizzato insieme ai nomi di dominio example.com o example.net nella documentazione del fornitore e del protocollo. Gli indirizzi all'interno di questo blocco non devono apparire su Internet pubblico.

Per dormire per 123 millisecondi, utilizzare ping 192.0.2.1 -n 1 -w 123 >nul


Sì, è più facile da scrivere e capire che doverne aggiungere uno al -nparametro.
Peter Mortensen,

Tuttavia, l'ho misurato (usando 100 ping). Se uso -n 3 -w 124, il tempo effettivo è esattamente (3 + 1) * (124 + 1) = 4 * 125 = 500 ms. Il tempismo è sorprendentemente stabile, esatto alla risoluzione di 10 ms nella lettura (da un prompt CMD con tempo) - e la risoluzione sottostante è decisamente migliore di 10 ms (non influenzata dalla solita risoluzione tick di 16 ms).
Peter Mortensen,

@mafu Il fatto che 192.0.2.0/24 non debba essere usato non significa che non possa essere usato e quindi non è realmente garantito che non ci sia risposta sulle richieste di eco. Ad esempio, configurare per qualsiasi PC Windows l'indirizzo IPv4 statico 192.0.2.1 e la maschera di sottorete 255.255.255.0 e collegare la scheda di rete a qualsiasi altro dispositivo. È sufficiente un semplice interruttore a cui non è collegato nient'altro. Quindi eseguire ping 192.0.2.1su questo PC Windows e si può vedere che lo stack TCP / IP di Windows risponde alle richieste di eco. Quante persone sanno che 192.0.2.0/24 non dovrebbe essere usato per un indirizzo IPv4 statico?
Mofi,

1
Per la discussione nei commenti qui , sembra che 192.0.2.1 non sia poi così infallibile e alcuni suggeriscono che 127.255.255.255 sia una scelta migliore. Pensieri?
JLRishe

I commenti menzionati nel post sopra sono stati ora rimossi (probabilmente come NLN), ma sarei d'accordo con la modifica a 127.255.255.255causa del fatto che è un indirizzo di loopback di trasmissione in Windows che è già assegnato per impostazione predefinita (è possibile confermare eseguendo route printin cmd e guardando attraverso la tabella di instradamento IPv4 che stampa).
Hoppeduppeanut

6

Se hai PowerShell sul tuo sistema, puoi semplicemente eseguire questo comando:

powershell -command "Start-Sleep -s 1"

Modifica: da mia risposta su un thread simile , le persone hanno sollevato un problema in cui la quantità di tempo necessaria per avviare PowerShell è significativa rispetto a quanto tempo stai cercando di aspettare. Se l'accuratezza del tempo di attesa è importante (cioè un secondo o due ritardi extra non sono accettabili), è possibile utilizzare questo approccio:

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

Questo richiede il tempo in cui è stato emesso il comando windows e lo script PowerShell rimane inattivo fino a 5 secondi dopo tale orario. Quindi, fino a quando PowerShell impiega meno tempo per iniziare rispetto alla durata del sonno, questo approccio funzionerà (sono circa 600 ms sulla mia macchina).


6
timeout /t <seconds> <options>

Ad esempio, per fare in modo che lo script esegua un'attesa ininterrotta di 2 secondi:

timeout /t 2 /nobreak >NUL

Ciò significa che lo script attenderà 2 secondi prima di continuare.

Per impostazione predefinita, una sequenza di tasti interromperà il timeout, quindi utilizzare l' /nobreakinterruttore se non si desidera che l'utente sia in grado di interrompere (annullare) l'attesa. Inoltre, il timeout fornirà notifiche al secondo per avvisare l'utente per quanto tempo resta da attendere; questo può essere rimosso reindirizzando il comando aNUL .

modifica: Come sottolinea @martineau nei commenti , il timeoutcomando è disponibile solo su Windows 7 e versioni successive. Inoltre, il pingcomando utilizza meno tempo del processore rispetto a timeout. Credo ancora nell'utilizzare, timeoutove possibile, poiché è più leggibile pingdell'hacking. Leggi di più qui .


2
Apparentemente questo comando è disponibile solo in Windows 7/2008 e XP Resource Kit (e possibilmente 8 / 8.1). La fonte afferma inoltre che l' pingapproccio utilizza meno tempo del processore.
martineau,

5

Basta inserirlo nel file batch in cui si desidera attendere.

@ping 127.0.0.1 -n 11 -w 1000 > null

In cosa differisce dalla risposta di paxdiablo?
Peter Mortensen,

2
Non è diverso, ma le risposte qui sono da più domande unite, quindi non tutte le risposte esistevano quando ho risposto.
Brent Stewart,

4

Nel Blocco note, scrivi:

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

Ora salva come wait.bat nella cartella C: \ WINDOWS \ System32, quindi ogni volta che vuoi aspettare, usa:

CALL WAIT.bat <whole number of seconds without quotes>

Si ripete ripetutamente, aspettando un secondo tra ogni ping e poi ritorna al programma chiamante, non vedo il ciclo infinito, ma l'ho testato da solo.
SuperKael,

Errore mio, non esiste un ciclo infinito. Tuttavia, come menzionato in una delle altre risposte , è meglio pingqualcosa non solo una volta e utilizzare l' -w Timeoutopzione per il ritardo in millisecondi piuttosto che l' -n Countintera opzione del numero di tentativi.
martineau,

-w Timeoutpotrebbe essere migliore, ma mi sono assicurato che esegua il ping una volta in più rispetto al tempo inserito.
SuperKael,

4

Il Resource Kit ha sempre incluso questo. Almeno da Windows 2000.

Inoltre, il pacchetto Cygwin ha un sleepplop nel tuo PERCORSO e include il cygwin.dll(o come si chiama) e la strada da percorrere!


2
Si noti che cygwin1.dll non coesiste pacificamente con diverse versioni di se stesso. Faresti meglio ad avere un solo cygwin1.dll sul tuo computer, o otterrai strani errori.
JesperE,

Quale kit di risorse? Sembra che ce ne sia più di uno. Puoi aggiornare la tua risposta?
Peter Mortensen,

3

Mi piace la risposta di Aacini . L'ho aggiunto per gestire il giorno e consentirgli anche di gestire centisecondi ( %TIME%output 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

3

Ho usato questo programma di sonno C #. Potrebbe essere più conveniente per te se C # è la tua lingua preferita:

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

3

Ancora più leggero della soluzione Python è un rivestimento Perl.

Per dormire per sette secondi, inseriscilo nello script BAT:

perl -e "sleep 7"

Questa soluzione fornisce solo una risoluzione di un secondo.

Se hai bisogno di una risoluzione più alta, usa il modulo Time :: HiRes di CPAN. Fornisce usleep()quali dormono in microsecondi e nanosleep()quali dormono in nanosecondi (entrambe le funzioni accettano solo argomenti interi). Vedi la domanda Stack Overflow Come posso dormire per un millisecondo in Perl? per ulteriori dettagli.

Ho usato ActivePerl per molti anni. È molto facile da installare.


2

O riga di comando Python, ad esempio, per 6 secondi e mezzo:

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

Sebbene più breve, questo è un duplicato della risposta accettata.
Peter Mortensen,

@Peter Mortensen: ti consente anche di inserire facilmente tutto in una singola riga di un file batch.
martineau,

2

L'uso del ping è buono, purché tu voglia solo "aspettare un po '". Questo perché dipendi da altre funzioni sottostanti, come la tua rete funzionante e dal fatto che non c'è nulla di risposta su 127.0.0.1. ;-) Forse non è molto probabile che fallisca, ma non è impossibile ...

Se vuoi essere sicuro che stai aspettando esattamente il tempo specificato, dovresti usare il sleep funzionalità (che ha anche il vantaggio di non utilizzare la potenza della CPU o attendere che una rete sia pronta).

Trovare un eseguibile già creato per il sonno è il modo più conveniente. Rilascialo nella cartella Windows o in qualsiasi altra parte del percorso standard ed è sempre disponibile.

Altrimenti, se disponi di un ambiente di compilazione, puoi crearne uno tu stesso. La Sleepfunzione è disponibile in kernel32.dll, quindi devi solo usare quella. :-) Per VB / VBA dichiarare quanto segue all'inizio della sorgente per dichiarare una funzione sleep:

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

Per C #:

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

Ulteriori informazioni su questa funzionalità (disponibile da Windows 2000) sono disponibili nella funzione Sleep (MSDN).

Nello standard C, sleep()è incluso nella libreria standard e in Visual Studio C di Microsoft la funzione è denominata Sleep(), se la memoria mi serve. ;-) Quei due prendono l'argomento in pochi secondi, non in millisecondi come le due dichiarazioni precedenti.


1
Sleep è disponibile nel framework .net - dai un'occhiata alla classe thread, ad esempio: utilizzando System.Threading; .... Thread.Sleep (1000);
John Sibly,

2
Se "ping 127.0.0.1" fallisce, hai cose più serie di "sleep" di cui preoccuparti: questa è l'interfaccia di loopback, qualsiasi cosa RPC probabilmente impazzirà.
Piskvor lasciò l'edificio il

2

La migliore soluzione che dovrebbe funzionare su tutte le versioni di Windows dopo Windows 2000 sarebbe:

timeout numbersofseconds /nobreak > nul

Non funziona su XP Pro ...'timeout' is not recognized as an internal or external command, operable program or batch file.
martineau

1

Pathping.exe può dormire meno del secondo.

@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

1

Sono impressionato da questo:

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

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

Tecnicamente, stai dicendo al choicecomando di accettare solo y. Il valore predefinito è y, per farlo in 5 secondi, per non disegnare alcun prompt e per scaricare tutto ciò che dice a NUL (come un terminale null su Linux).


3
Mi eccomi qui: non lo consiglio affatto. Nelle CHOICEversioni che conosco, se qualcuno preme un tasto durante l'attesa, cosa che a volte fanno persone impazienti, la scelta leggerà un input, emetterà un segnale acustico di sistema per un input errato e fermerà il conto alla rovescia, quindi si bloccherà a meno che non premano Y. E se capita semplicemente di premere Y, allora la scelta finisce lì invece di aspettare 5. Inoltre, questa scelta sta usando una sintassi Vista davvero strana. I normali comandi di scelta invece li usano CHOICE /T:Y,5 > NUL. (Non c'è il flag / D nelle vecchie versioni.) E se hai Vista, usa TIMEOUTinvece.
Coding With Style

1

È inoltre possibile utilizzare un file .vbs per eseguire timeout specifici:

Il codice seguente crea il file .vbs. Metti questo nella parte superiore del tuo codice rbatch:

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

Il codice seguente apre quindi i file .vbs e specifica per quanto tempo attendere:

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

Nel codice sopra, "1000" è il valore del ritardo da inviare al file .vbs in millisecondi, ad esempio 1000 ms = 1 s. Puoi modificare questa parte in modo che sia lungo quanto desideri.

Il codice seguente elimina il file .vbs dopo aver terminato. Metti questo alla fine del tuo file batch:

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

Ed ecco il codice tutti insieme, quindi è facile da copiare:

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

1

Da Windows Vista in poi hai i comandi TIMEOUT e SLEEP , ma per usarli su Windows XP o Windows Server 2003, avrai bisogno del kit di strumenti di risorse di Windows Server 2003 .

Qui hai una buona panoramica delle alternative di sospensione (l'approccio ping è il più popolare in quanto funzionerà su ogni macchina Windows), ma ce n'è (almeno) uno non menzionato che (ab) usa il W32TMcomando (Time Service):

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

Dove dovresti sostituire la N con i secondi che vuoi mettere in pausa. Inoltre, funzionerà su tutti i sistemi Windows senza prerequisiti.

Typeperf può anche essere utilizzato:

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

Con mshta e javascript (può essere utilizzato per dormire in meno di un secondo):

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

Questo dovrebbe essere ancora più preciso (per aspettare meno di un secondo) - eseguibile autocompilante basandosi su .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);
}

1

Esistono molti modi per realizzare un ' sleep ' in cmd / batch:

Il mio preferito:

TIMEOUT /NOBREAK 5 >NUL 2>NUL

Ciò arresterà la console per 5 secondi, senza alcun output.

Più usato:

ping localhost -n 5 >NUL 2>NUL

Questo proverà a stabilire una connessione per localhost5 volte. Dal momento che è ospitato sul tuo computer, raggiungerà sempre l'host, quindi ogni secondo proverà il nuovo ogni secondo. Il -nflag indica quante volte lo script tenterà la connessione. In questo caso è 5, quindi durerà 5 secondi.

Varianti dell'ultima:

ping 1.1.1.1 -n 5 >nul

In questo script ci sono alcune differenze comparandolo con l'ultimo. Questo non proverà a chiamare localhost. Invece, proverà a connettersi a 1.1.1.1un sito Web molto veloce. L'azione durerà 5 secondi solo se si dispone di una connessione Internet attiva. Altrimenti durerà circa 15 per completare l'azione . Non consiglio di usare questo metodo.

ping 127.0.0.1 -n 5 >nul

Questo è esattamente lo stesso dell'esempio 2 (il più usato). Inoltre, puoi anche usare:

ping [::1] -n 5 >nul

Questo invece utilizza la localhostversione di IPv6 .

Esistono molti metodi per eseguire questa azione. Tuttavia, preferisco il metodo 1 per Windows Vista e versioni successive e il metodo più utilizzato (metodo 2) per le versioni precedenti del sistema operativo.


0

Puoi divertirti mettendo il messaggio PAUSA nella barra del titolo:

@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

0

Questo è stato testato su Windows XP SP3 e Windows 7 e utilizza CScript. Ho inserito alcune protezioni per evitare il "" suggerimento. ( /qsarebbe pericoloso)

Aspetta un secondo:

sleepOrDelayExecution 1000

Attendi 500 ms e poi esegui le cose dopo:

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

0

Poiché altri stanno suggerendo programmi di terze parti (Python, Perl, app personalizzate, ecc.), Un'altra opzione è GNU CoreUtils per Windows disponibile su http://gnuwin32.sourceforge.net/packages/coreutils.htm .

2 opzioni per la distribuzione:

  1. Installa il pacchetto completo (che includerà la suite completa di CoreUtils, dipendenze, documentazione, ecc.).
  2. Installa solo il binario 'sleep.exe' e le dipendenze necessarie (usa depend.exe per ottenere dipendenze).

Uno dei vantaggi della distribuzione di CoreUtils è che otterrai anche una serie di altri programmi utili per gli script (il batch di Windows lascia molto a desiderare).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.