Schlafen in einer Batch-Datei

151

Wenn ich eine Batch-Datei schreibe, um etwas auf einer Windows-Box zu automatisieren, musste ich die Ausführung einige Sekunden lang anhalten (normalerweise in einer Test- / Warteschleife, um auf den Start eines Prozesses zu warten). Zu der Zeit verwendet die beste Lösung, die ich finden konnte, Ping (ich mache dir nichts vor), um den gewünschten Effekt zu erzielen. Ich habe hier eine bessere Beschreibung gefunden , die eine aufrufbare "wait.bat" beschreibt, die wie folgt implementiert ist:

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

Sie können dann Aufrufe von wait.bat in Ihre eigene Batch-Datei aufnehmen und dabei die Anzahl der Sekunden für den Ruhezustand angeben.

Anscheinend bietet das Windows 2003 Resource Kit (endlich!) Einen Unix-ähnlichen Schlafbefehl . Gibt es in der Zwischenzeit für diejenigen von uns, die noch Windows XP, Windows 2000 oder (leider) Windows NT verwenden , einen besseren Weg?

Ich habe das sleep.pySkript in der akzeptierten Antwort so geändert , dass es standardmäßig eine Sekunde beträgt, wenn in der Befehlszeile keine Argumente übergeben werden:

import time, sys

time.sleep(float(sys.argv[1]) if len(sys.argv) > 1 else 1)
Jason Etheridge
quelle
Auf der Microsoft- Downloadseite des Windows 2003 Resource Kit wird angegeben, dass es auch für XP funktioniert. Ich fürchte, es gibt keine andere Wahl, als ein 'externes' Dienstprogramm zu verwenden, um das Warten zu erledigen: Es gibt nichts Vergleichbares im XP-Befehlsprozessor.
GerG
Das 2003 Server Resource Kit funktioniert mit Windows XP (und wahrscheinlich mit w2k)
Martin Beckett
Ich hatte in der Vergangenheit das gleiche Problem und ping mich selbst an (mit einer Bemerkung oben, die deutlich dokumentiert, dass mir klar ist, dass dies dumm ist :)).
Jack Leow
2
Sie haben mehrere Möglichkeiten: Emulieren Sie einen Ruhezustand mit dem pingBefehl oder laden Sie das Windows Resource Kit herunter, das einen sleepBefehl enthält. Weitere Details hier: Batch-Datei SLEEP Command
Rudu

Antworten:

14

AKTUALISIEREN

Der timeoutBefehl, der ab Windows Vista verfügbar ist, sollte der verwendete Befehl sein, wie in einer anderen Antwort auf diese Frage beschrieben. Was hier folgt, ist eine alte Antwort.

Alte Antwort

Wenn Sie Python installiert haben oder nichts dagegen haben (es hat auch andere Verwendungszwecke :), erstellen Sie einfach das folgende sleep.py- Skript und fügen Sie es irgendwo in Ihren PATH ein:

import time, sys

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

Es werden Pausen von weniger als einer Sekunde (z. B. 1,5 Sekunden, 0,1 Sekunden usw.) zugelassen, falls Sie dies benötigen. Wenn Sie es als sleepund nicht aufrufen möchten, sleep.pykönnen Sie die .PYErweiterung Ihrer Umgebungsvariablen PATHEXT hinzufügen . Unter Windows XP können Sie es bearbeiten in:

Arbeitsplatz → Eigenschaften (Menü) → Erweitert (Registerkarte) → Umgebungsvariablen (Schaltfläche) → Systemvariablen (Rahmen)

tzot
quelle
31
Warum sollten wir ein Skript in Python schreiben, wenn eine stapelskriptfähige Lösung angefordert wird? Wie kann die Pfaderweiterung das Problem lösen, dass Windows-Benutzer keinen Python-Interpreter installiert haben? Vielen Dank.
Val
6
Aus Gründen der Portabilität denke ich, dass diese Lösung vermieden werden sollte, da es vollkommen gute native Alternativen gibt.
Gras Double
1
Dieser Ansatz hat in der Vergangenheit möglicherweise eine Problemumgehung bereitgestellt, aber die von @Blorgbeard beschriebene native Lösung ist definitiv der richtige Weg.
Mike
226

Der timeoutBefehl ist ab Windows Vista verfügbar:

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

Hinweis: Es funktioniert nicht mit der Eingabeumleitung - triviales Beispiel:

C:\>echo 1 | timeout /t 1 /nobreak
ERROR: Input redirection is not supported, exiting the process immediately.
Blorgbeard ist raus
quelle
8
funktioniert nicht bei konsolenlosen Anwendungen: "FEHLER: Die Umleitung von Eingaben wird nicht unterstützt, wodurch der Prozess sofort beendet wird."
Simpleuser
Ich meinte Fälle, in denen Sie überhaupt keine Konsole haben, z. B. wenn die Batchdatei im Hintergrund über einen Fork eines anderen Prozesses, eine Cygwin Crontab oder einen Remote-SSH-Befehl usw. ausgeführt wird.
simpleuser
1
Oh ja, ich weiß. Das Beispiel, das ich gegeben habe, war nur, um den Fehler zu demonstrieren :)
Blorgbeard ist
3
Der von @Cristian Ciupitu hinzugefügte Link zur Dokumentation für timeoutist teilweise falsch - Windows XP verfügt nicht über diesen Befehl.
Martineau
1
@HelloWorld, das klingt wie ein Problem mit Ihrem% PATH%
Blorgbeard ist am
21

Mit der beschriebenen pingMethode mache ich das, wenn ich keine weiteren ausführbaren Dateien hinzufügen kann (oder will) oder keine andere Software installieren kann.

Sie sollten etwas pingen, das nicht vorhanden ist, und das -wFlag verwenden, damit es nach dieser Zeit fehlschlägt, und nicht etwas pingen, das vorhanden ist (wie localhost) -n. Auf diese Weise können Sie die Zeit in weniger als einer Sekunde verarbeiten, und ich denke, sie ist etwas genauer.

z.B

(Test, dass 1.1.1.1 nicht genommen wird)

ECHO Waiting 15 seconds

PING 1.1.1.1 -n 1 -w 15000 > NUL
  or
PING -n 15 -w 1000 127.1 >NUL
Daniel
quelle
PING: transmit failed. General failure.
Kommt sofort
Die IP 1.1.1.1wird von CloudFlare übernommen, sodass dies nicht 15 Sekunden, sondern einige ms dauert.
Dhcgn
16

SLEEP.exeist in den meisten Resource Kits enthalten, z. B. dem Windows Server 2003 Resource Kit, das auch unter Windows XP installiert werden kann.

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

Ich bin mit den Antworten, die ich hier gefunden habe, nicht einverstanden.

Ich verwende die folgende Methode, die vollständig auf den Windows XP-Funktionen basiert, um eine Verzögerung in einer Batchdatei auszuführen:

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

Sie können den Tag auch in die Berechnung einfügen, damit die Methode auch funktioniert, wenn das Verzögerungsintervall über Mitternacht liegt.

Aacini
quelle
15
Dies sollte korrekt sein, ist jedoch ein CPU-intensiver Weg. Normalerweise möchten Sie eine Interrupt-gesteuerte Implementierung, damit der Prozess keine CPU-Zyklen verbraucht, während er wartet. Dies sollte bei seltenen kurzen Wartezeiten kein Problem sein, wie dies wahrscheinlich in den meisten Batch-Situationen der Fall ist. Ein kontinuierlich laufender Prozess mit langen Wartezeiten kann sich jedoch negativ auf die Systemleistung auswirken.
Dbenham
4
Da die Systemuhr verwendet wird, beträgt die Genauigkeit eine Sekunde. Wenn 2 Sekunden angegeben sind, kann die Verzögerung zwischen 2 Sekunden und 3 Sekunden liegen (tatsächlich 2,99999 ... Sekunden).
Peter Mortensen
Was ist, wenn die Zeit jetzt 7:59:59 ist und Sie 7 Sekunden warten möchten? Das scheint das nicht zu berücksichtigen.
Asche999
Dies verbraucht mehr CPU-Zeit als die Systemzeit zählt. Außerdem führen Sie arithmetische Operationen mit Oktalzahlen aus, da Minuten und Sekunden kleiner als 10 mit einer führenden 0 im TIMEBefehl angezeigt werden .
Andreas
2
@mrt: Das Problem ist, dass Sie %TIME%ein Komma verwenden, um die Centisekunden anstelle eines Punktes zu trennen! DELIMS=:.,"
Fügen Sie
13

Ich hatte ein ähnliches Problem, aber ich habe gerade eine sehr kurze C ++ - Konsolenanwendung aufgerufen, um dasselbe zu tun. Führen Sie einfach MySleep.exe 1000 aus - vielleicht einfacher als das Herunterladen / Installieren des gesamten Resource Kits.

#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
quelle
10

Drüben bei Server Fault wurde eine ähnliche Frage gestellt , und die Lösung dort war:

choice /d y /t 5 > nul
mlsteeves
quelle
7
Zu Ihrer Information: Auswahl ist in Windows XP nicht enthalten. Es war in Windows 9x, wurde von XP entfernt und ab Vista wieder hinzugefügt.
Devin Burke
7
Ich empfehle das überhaupt nicht. Zumindest in allen CHOICEmir bekannten Versionen, wenn jemand während des Wartens einen Knopf drückt, was ungeduldige Leute manchmal tun, registriert die Auswahl eine Eingabe, gibt einen Systemton für eine schlechte Eingabe aus und stoppt den Countdown-Timer, was bedeutet, dass er hängen bleibt dort, es sei denn, sie drücken N oder Y. Und wenn sie zufällig einen dieser beiden drücken, endet die Auswahl genau dort, anstatt auf 5 zu warten. Außerdem verwendet diese Auswahl eine wirklich seltsame Vista-Syntax. Alle normalen Auswahlbefehle würden stattdessen dafür verwendet CHOICE /T:Y,5 > NUL. /DIn den alten Versionen gibt es keine Flagge.
Codierung mit Stil
1
Um das Ganze abzurunden, haben zumindest die mir bekannten CHOICE-Befehle je nach Sprache unterschiedliche Standard-Ja / Nein-Schaltflächen. Wenn Sie sich also zufällig auf eine Standardauswahl [J, N] verlassen, anstatt sie explizit mit /C:YNoder nur anzugeben /C:YDies wird nicht funktionieren, wenn jemand beispielsweise einen schwedischen Auswahlbefehl hat, der wahrscheinlich standardmäßig ein [J, N] ausführt. Das steckt also in allen möglichen Schwierigkeiten.
Codierung mit Stil
1
@Coding In Win7 getestet. Wenn der Benutzer eine Taste drückt, ertönt ein Piepton. Nach weiteren 5 Sekunden, nachdem der Benutzer eine Taste gedrückt hat, tritt jedoch eine Zeitüberschreitung auf. Wenn der Benutzer also weiterhin Tasten drückt, tritt keine Zeitüberschreitung auf. In meinem Fall, als ich dies benutzte, glaube ich, dass die Konsole ausgeblendet wird, so dass der Benutzer die Taste nicht drücken konnte. Auf diesem System gab es keinen Zugriff auf Python, es gab keinen Zugriff, um meine eigene Exe auf dem System abzulegen (wie in einigen anderen Antworten vorgeschlagen), ich war ziemlich eingeschränkt in dem, was ich tun konnte. Also, was würden Sie empfehlen?
mlsteeves
@mlsteeves Jedes Windows, DOS usw. hat einen anderen Auswahlbefehl und ist, wie bereits erwähnt, normalerweise nicht in XP verfügbar. Viele Auswahlbefehle haben ein subtil unterschiedliches Verhalten und einige haben sogar eine andere Syntax. Ich benutze normalerweise den Ping-Befehl, wenn ich einen Schlaf brauche. Es ist hässlich, aber zuverlässig.
Codierung mit Stil
9

Sie können die Windows- cscript-WSH- Ebene und diese JavaScript-Datei wait.js verwenden:

if (WScript.Arguments.Count() == 1)
    WScript.Sleep(WScript.Arguments(0)*1000);
else
    WScript.Echo("Usage: cscript wait.js seconds");
Blake7
quelle
1
Der Windows Scripting Host kann jedoch über Gruppenrichtlinien deaktiviert werden.
Joey
8

Verwenden Sie je nach Ihren Kompatibilitätsanforderungen Folgendes ping:

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

zB um 5 Sekunden zu warten, verwenden Sie

ping -n 6 localhost >nul 2>&1

oder unter Windows 7 oder höher verwenden timeout:

timeout 6 >nul
Joey
quelle
2
-wist in Millisekunden, -nist nur die Anzahl der Pings und die Standardzeit zwischen den Pings ist eine Sekunde.
Joey
8

Sie können Ping verwenden:

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

Es wird 10 Sekunden warten.

Der Grund, warum Sie 11 verwenden müssen, ist, dass der erste Ping sofort erlischt und nicht nach einer Sekunde. Die Anzahl sollte immer eins mehr sein als die Anzahl der Sekunden, die Sie warten möchten.

Denken Sie daran, dass der Zweck des -wnicht darin besteht, eine Sekunde zu warten. Damit stellen Sie sicher, dass Sie bei Netzwerkproblemen nicht länger als eine Sekunde warten . pingalleine sendet ein ICMP-Paket pro Sekunde. Es ist wahrscheinlich nicht für localhost erforderlich, aber alte Gewohnheiten sterben schwer.

paxdiablo
quelle
Es wird nicht empfohlen, dies für die kritische Echtzeitverarbeitung zu verwenden. Da der PING-Befehl verwendet wird, ist es möglich, dass diese WAIT-Batchdatei einige Millisekunden lang ausgeführt wird
Wael Dalloul,
12
@Wael, wenn Sie über das Warten an einer Sekunde sprechen, sind einige Millisekunden irrelevant. Und wenn Sie cmd.exe für Echtzeit-Sachen verwenden, verdienen Sie alles, was Sie bekommen :-)
paxdiablo
-w ist ein Timeout-Wert. Es ist die Anzahl der Millisekunden, die auf eine Antwort gewartet werden muss ... nicht die Zeit, die zwischen den Pings gewartet werden muss .
Quux
@quux, nirgends habe ich angegeben, dass -wdas Zeitlimit (obwohl ich zugeben kann, dass einige aufgrund meiner Unklarheit darauf schließen können) tatsächlich dazu verwendet wird, die Zykluszeit zu begrenzen, wenn Netzwerkprobleme auftreten, die dazu führen würden, dass jeder Zyklus mehr als die zugewiesene Zeit benötigt zweite. Ich habe am Ende einen Absatz hinzugefügt, um dies zu verdeutlichen.
Paxdiablo
Das Problem ist, dass Sie zwischen den Pings möglicherweise keine volle Sekunde warten müssen , wenn Pings schneller zurückkehren . So wird Ihre Warteschleife schneller enden, als Sie gedacht haben
Quux
7

Es gibt eine bessere Möglichkeit, mit Ping zu schlafen. Sie möchten eine Adresse anpingen, die nicht vorhanden ist, damit Sie ein Zeitlimit mit Millisekundengenauigkeit angeben können. Glücklicherweise ist eine solche Adresse in einem Standard (RFC 3330) definiert und ist es auch 192.0.2.x. Dies ist nicht erfunden, es ist wirklich eine Adresse mit dem alleinigen Zweck, nicht zu existieren (es ist möglicherweise nicht klar, aber es gilt auch in lokalen Netzwerken):

192.0.2.0/24 - Dieser Block wird als "TEST-NET" zur Verwendung in Dokumentation und Beispielcode zugewiesen. Es wird häufig in Verbindung mit den Domainnamen example.com oder example.net in der Hersteller- und Protokolldokumentation verwendet. Adressen in diesem Block sollten nicht im öffentlichen Internet angezeigt werden.

Verwenden Sie, um 123 Millisekunden zu schlafen ping 192.0.2.1 -n 1 -w 123 >nul

Mafu
quelle
Ja, dies ist einfacher zu schreiben und zu verstehen, als dem Parameter einen hinzuzufügen-n .
Peter Mortensen
Ich habe es jedoch gemessen (mit 100 Pings). Wenn ich -n 3 -w 124 verwende, ist die tatsächliche Zeit genau (3 + 1) * (124 + 1) = 4 * 125 = 500 ms. Das Timing ist überraschend stabil, genau auf die 10-ms-Auflösung in der Anzeige (durch eine CMD-Eingabeaufforderung mit der Zeit) - und die zugrunde liegende Auflösung ist definitiv besser als 10 ms (nicht beeinflusst von der üblichen 16-ms-Tick-Auflösung).
Peter Mortensen
@mafu Dass 192.0.2.0/24 nicht verwendet werden sollte, bedeutet nicht, dass es nicht verwendet werden kann, und daher kann nicht wirklich garantiert werden, dass auf die Echoanforderung (en) keine Antwort erfolgt. Konfigurieren Sie beispielsweise für jeden Windows-PC die statische IPv4-Adresse 192.0.2.1 und die Subnetzmaske 255.255.255.0 und verbinden Sie den Netzwerkadapter mit einem anderen Gerät. Ein einfacher Schalter reicht aus, an den sonst nichts angeschlossen ist. Führen Sie dann ping 192.0.2.1auf diesem Windows-PC aus, und es ist ersichtlich, dass der Windows TCP / IP-Stapel auf die Echoanforderungen antwortet. Wie viele Personen wissen, dass 192.0.2.0/24 nicht für eine statische IPv4-Adresse verwendet werden sollte?
Mofi
1
Laut der Diskussion in den Kommentaren hier scheint 192.0.2.1 nicht allzu narrensicher zu sein, und einige schlagen vor, dass 127.255.255.255 eine bessere Wahl ist. Gedanken?
JLRishe
Die Kommentare in der Post oben erwähnten jetzt entfernt wurden (wahrscheinlich als NLN-), aber ich würde mit der Änderung zustimmen 127.255.255.255weil es eine Broadcast - Loopback - Adresse in Windows ist , die bereits standardmäßig zugeordnet ist (Sie können dies bestätigen , indem Sie route printin cmd und Durchsuchen der IPv4-Routentabelle, die gedruckt wird).
Hoppeduppeanut
6

Wenn Sie PowerShell auf Ihrem System haben, können Sie einfach diesen Befehl ausführen:

powershell -command "Start-Sleep -s 1"

Bearbeiten: Aus meiner Antwort auf einen ähnlichen Thread haben die Leute ein Problem angesprochen, bei dem die Zeit, die Powershell zum Starten benötigt, im Vergleich zu der Zeit, auf die Sie warten möchten, erheblich ist. Wenn die Genauigkeit der Wartezeit wichtig ist (dh eine zusätzliche Verzögerung von ein oder zwei Sekunden nicht akzeptabel ist), können Sie diesen Ansatz verwenden:

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

Dies dauert einige Zeit, bis der Windows-Befehl ausgegeben wurde, und das Powershell-Skript wird bis zu 5 Sekunden nach dieser Zeit in den Ruhezustand versetzt. Solange der Start von Powershell weniger Zeit in Anspruch nimmt als Ihre Schlafdauer, funktioniert dieser Ansatz (auf meinem Computer sind es ungefähr 600 ms).

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

So führen Sie das Skript beispielsweise zu einer unterbrechungsfreien Wartezeit von 2 Sekunden:

timeout /t 2 /nobreak >NUL

Das heißt, das Skript wartet 2 Sekunden, bevor es fortfährt.

Standardmäßig unterbricht ein Tastendruck das Zeitlimit. Verwenden /nobreakSie daher den Schalter, wenn der Benutzer das Warten nicht unterbrechen (abbrechen) soll. Darüber hinaus werden durch das Zeitlimit Benachrichtigungen pro Sekunde bereitgestellt, um den Benutzer darüber zu informieren, wie lange noch gewartet werden muss. Dies kann durch Weiterleiten des Befehls an entfernt werden NUL.

Bearbeiten: Wie @martineau in den Kommentaren ausführt , ist der timeoutBefehl nur unter Windows 7 und höher verfügbar. Darüber hinaus benötigt der pingBefehl weniger Prozessorzeit als timeout. Ich glaube jedoch immer noch daran timeout, wenn möglich zu verwenden, da es besser lesbar ist als der ping"Hack". Lesen Sie hier mehr .

mgthomas99
quelle
2
Anscheinend ist dieser Befehl nur in Windows 7/2008 und im XP Resource Kit (und möglicherweise 8 / 8.1) verfügbar. Die Quelle behauptet auch, dass der pingAnsatz weniger Prozessorzeit benötigt.
Martineau
5

Fügen Sie dies einfach in Ihre Batch-Datei ein, wo Sie warten möchten.

@ping 127.0.0.1 -n 11 -w 1000 > null
Brent Stewart
quelle
Wie unterscheidet sich das von Paxdiablos Antwort?
Peter Mortensen
2
Es ist nicht anders, aber die Antworten hier stammen aus mehreren zusammengeführten Fragen, sodass nicht alle Antworten vorhanden waren, als ich antwortete.
Brent Stewart
4

Schreiben Sie im Editor:

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

Speichern Sie nun als wait.bat im Ordner C: \ WINDOWS \ System32. Verwenden Sie dann, wann immer Sie warten möchten:

CALL WAIT.bat <whole number of seconds without quotes>
SuperKael
quelle
Es pingt sich wiederholt an und wartet eine Sekunde zwischen jedem Ping. Dann kehrt es zum aufrufenden Programm zurück. Ich sehe die Endlosschleife nicht, aber ich habe sie selbst getestet.
SuperKael
Mein Fehler, es gibt keine Endlosschleife. Wie in einer der anderen Antworten erwähnt , ist es jedoch besser, pingnicht nur einmal etwas zu tun und die -w TimeoutOption für die Verzögerungszeit in Millisekunden zu verwenden, als die Option für die -n Countgesamte Anzahl der Wiederholungen.
Martineau
-w Timeoutmag besser sein, aber ich habe dafür gesorgt, dass es noch einmal pingt als die eingegebene Zeit.
SuperKael
4

Das Resource Kit hat dies immer enthalten. Zumindest seit Windows 2000.

Außerdem hat das Cygwin-Paket einen sleep- Plop, der in Ihren PFAD einfügt und den cygwin.dll(oder wie auch immer er heißt) und den Weg vor sich hat!

Daren Thomas
quelle
2
Beachten Sie, dass cygwin1.dll nicht friedlich mit verschiedenen Versionen von sich selbst koexistiert. Sie sollten besser eine und nur eine cygwin1.dll auf Ihrem Computer haben, sonst werden Sie seltsame Fehler bekommen.
JesperE
Welches Resource Kit? Es scheint mehr als einen zu geben. Können Sie Ihre Antwort aktualisieren?
Peter Mortensen
3

Ich mag Aacinis Antwort . Ich habe es hinzugefügt, um den Tag zu verarbeiten und es auch für Centisekunden ( %TIME%Ausgaben H:MM:SS.CC) zu aktivieren :

: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
quelle
3

Ich habe dieses C # -Schlafprogramm verwendet. Es ist möglicherweise bequemer für Sie, wenn C # Ihre bevorzugte Sprache ist:

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

Noch leichter als die Python-Lösung ist ein Perl-Einzeiler.

Um sieben Sekunden lang zu schlafen, geben Sie dies in das BAT-Skript ein:

perl -e "sleep 7"

Diese Lösung bietet nur eine Auflösung von einer Sekunde.

Wenn Sie eine höhere Auflösung benötigen, verwenden Sie das Time :: HiRes-Modul von CPAN. Es gibt an, usleep()welche in Mikrosekunden und nanosleep()welche in Nanosekunden schlafen (beide Funktionen akzeptieren nur ganzzahlige Argumente). Siehe die Frage zum Stapelüberlauf. Wie schlafe ich eine Millisekunde in Perl? für weitere Details.

Ich benutze ActivePerl seit vielen Jahren. Es ist sehr einfach zu installieren.

Peter Mortensen
quelle
2

Oder Befehlszeilen-Python zum Beispiel für 6 ½ Sekunden:

python -c "import time;time.sleep(6.5)"
Alex Robinson
quelle
Obwohl kürzer, ist dies ein Duplikat der akzeptierten Antwort.
Peter Mortensen
@Peter Mortensen: Sie können damit auch einfach alles in eine einzelne Zeile einer Batch-Datei einfügen.
Martineau
2

Die Verwendung von Ping ist gut, solange Sie nur "ein bisschen warten" möchten. Dies liegt daran, dass Sie von anderen Funktionen abhängig sind, z. B. der Funktionsweise Ihres Netzwerks und der Tatsache, dass auf 127.0.0.1 keine Antwort erfolgt. ;-) Vielleicht ist es nicht sehr wahrscheinlich, dass es fehlschlägt, aber es ist nicht unmöglich ...

Wenn Sie sicher sein möchten, dass Sie genau auf die angegebene Zeit warten, sollten Sie die verwenden sleep Funktionalität verwenden (die auch den Vorteil hat, dass sie keine CPU-Leistung verbraucht oder darauf wartet, dass ein Netzwerk bereit ist).

Am bequemsten ist es, eine bereits für den Schlaf erstellte ausführbare Datei zu finden. Legen Sie es einfach in Ihrem Windows-Ordner oder einem anderen Teil Ihres Standardpfads ab und es ist immer verfügbar.

Wenn Sie eine Kompilierungsumgebung haben, können Sie diese auch einfach selbst erstellen. Die SleepFunktion ist in verfügbar kernel32.dll, Sie müssen sie also nur verwenden. :-) Für VB / VBA deklarieren Sie am Anfang Ihrer Quelle Folgendes, um eine Schlaffunktion zu deklarieren:

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

Für C #:

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

Weitere Informationen zu dieser Funktionalität (verfügbar seit Windows 2000) finden Sie hier in der Funktion "Ruhezustand" (MSDN).

In Standard C sleep()ist in der Standardbibliothek enthalten, und in Microsoft Visual Studio C wird die Funktion benannt Sleep(), wenn der Speicher mir dient. ;-) Diese beiden nehmen das Argument in Sekunden, nicht in Millisekunden wie die beiden vorherigen Erklärungen.

Tooony
quelle
1
Sleep ist im .net-Framework verfügbar. Sehen Sie sich die Thread-Klasse an, z. B.: Using System.Threading; .... Thread.Sleep (1000);
John Sibly
2
Wenn "ping 127.0.0.1" fehlschlägt, müssen Sie sich um ernstere Dinge als "Schlaf" Sorgen machen - dies ist die Loopback-Schnittstelle, alles, was RPC wahrscheinlich verrückt machen wird.
Piskvor verließ das Gebäude am
2

Die beste Lösung, die nach Windows 2000 auf allen Windows-Versionen funktionieren sollte, wäre:

timeout numbersofseconds /nobreak > nul
Tato
quelle
Funktioniert nicht mit XP Pro ...'timeout' is not recognized as an internal or external command, operable program or batch file.
Martineau
1

Die pathping.exe kann weniger als eine Sekunde schlafen.

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

Ich bin beeindruckt von diesem:

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

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

Technisch gesehen weisen Sie den choiceBefehl an, nur y zu akzeptieren. Der Standardwert ist y, um dies in 5 Sekunden zu tun, keine Eingabeaufforderung zu zeichnen und alles zu sichern, was es NUL sagt (wie Null-Terminal unter Linux).

Chris Moschini
quelle
3
Ich werde mich hier wiederholen: Ich empfehle dies überhaupt nicht. In den CHOICEmir bekannten Versionen wird, wenn jemand während des Wartens eine Taste drückt, was manchmal ungeduldige Leute tun, die Auswahl eine Eingabe lesen, einen Systemton für eine schlechte Eingabe geben und den Countdown anhalten, sodass er hängen bleibt, es sei denn, sie drücken Y. Und wenn sie zufällig Y drücken, endet die Auswahl genau dort, anstatt auf 5 zu warten. Außerdem verwendet diese Auswahl eine wirklich seltsame Vista-Syntax. Die normalen Auswahlbefehle verwenden stattdessen CHOICE /T:Y,5 > NULdafür. (In den alten Versionen gibt es kein / D-Flag.) Wenn Sie Vista haben, verwenden Sie TIMEOUTstattdessen.
Codierung mit Stil
1

Sie können auch eine .vbs-Datei verwenden, um bestimmte Zeitüberschreitungen durchzuführen:

Der folgende Code erstellt die .vbs-Datei. Fügen Sie dies oben in Ihren Rbatch-Code ein:

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

Der folgende Code öffnet dann die .vbs und gibt an, wie lange gewartet werden soll:

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

Im obigen Code ist "1000" der Wert der Zeitverzögerung, die in Millisekunden an die .vbs-Datei gesendet werden soll, z. B. 1000 ms = 1 s. Sie können diesen Teil so lange ändern, wie Sie möchten.

Der folgende Code löscht die .vbs-Datei, nachdem Sie damit fertig sind. Fügen Sie dies am Ende Ihrer Batch-Datei ein:

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

Und hier ist der Code zusammen, damit er leicht kopiert werden kann:

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

Von Windows Vista auf Sie haben TIMEOUT und SLEEP - Befehle, aber sie unter Windows XP oder Windows Server 2003 zu verwenden, müssen Sie den benötigen Windows Server 2003 Ressource - Tool - Kit .

Hier haben Sie einen guten Überblick über Schlafalternativen (der Ping-Ansatz ist der beliebteste, da er auf jedem Windows-Computer funktioniert), aber es gibt (mindestens) einen nicht erwähnten, der (ab) den W32TMBefehl (Zeitdienst) verwendet :

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

Wo Sie das N durch die Sekunden ersetzen sollten, die Sie anhalten möchten. Außerdem funktioniert es auf jedem Windows-System ohne Voraussetzungen.

Typeperf kann auch verwendet werden:

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

Mit mshta und Javascript (kann für den Schlaf unter einer Sekunde verwendet werden):

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

Dies sollte noch genauer sein (um weniger als eine Sekunde zu warten) - selbstkompilierende ausführbare Datei, die sich auf Folgendes stützt .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
quelle
1

Es gibt viele Möglichkeiten, einen " Schlaf " in cmd / batch zu erreichen:

Mein Liebling:

TIMEOUT /NOBREAK 5 >NUL 2>NUL

Dadurch wird die Konsole für 5 Sekunden ohne Ausgabe angehalten.

Am meisten benutzt:

ping localhost -n 5 >NUL 2>NUL

Dadurch wird versucht, eine Verbindung zu localhost5 Mal herzustellen . Da es auf Ihrem Computer gehostet wird, erreicht es immer den Host, sodass es jede Sekunde das Neue jede Sekunde ausprobiert. Das -nFlag gibt an, wie oft das Skript die Verbindung versucht. In diesem Fall ist es 5, es dauert also 5 Sekunden.

Varianten des letzten:

ping 1.1.1.1 -n 5 >nul

In diesem Skript gibt es einige Unterschiede im Vergleich zum letzten. Dies wird nicht versuchen anzurufen localhost. Stattdessen wird versucht, eine Verbindung zu 1.1.1.1einer sehr schnellen Website herzustellen. Die Aktion dauert nur 5 Sekunden , wenn Sie eine aktive Internetverbindung haben. Andernfalls dauert es ungefähr 15, um die Aktion abzuschließen . Ich empfehle diese Methode nicht.

ping 127.0.0.1 -n 5 >nul

Dies ist genau das gleiche wie in Beispiel 2 (am häufigsten verwendet). Sie können auch Folgendes verwenden:

ping [::1] -n 5 >nul

Dies verwendet stattdessen die IPv6- localhostVersion.

Es gibt viele Methoden, um diese Aktion auszuführen. Ich bevorzuge jedoch Methode 1 für Windows Vista und spätere Versionen und die am häufigsten verwendete Methode (Methode 2) für frühere Versionen des Betriebssystems.

Lumito
quelle
0

Sie können sich etwas einfallen lassen, indem Sie die PAUSE-Nachricht in die Titelleiste einfügen:

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

Dies wurde unter Windows XP SP3 und Windows 7 getestet und verwendet CScript. Ich habe einige sichere Wachen eingesetzt, um eine Aufforderung zu vermeiden. ( /qwäre gefährlich)

Warte eine Sekunde:

sleepOrDelayExecution 1000

Warten Sie 500 ms und führen Sie dann die folgenden Schritte aus:

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
Anonymer Feigling
quelle
0

Da andere Programme von Drittanbietern vorschlagen (Python, Perl, benutzerdefinierte App usw.), ist GNU CoreUtils für Windows eine weitere Option, die unter http://gnuwin32.sourceforge.net/packages/coreutils.htm verfügbar ist .

2 Optionen für die Bereitstellung:

  1. Installieren Sie das vollständige Paket (das die gesamte Suite von CoreUtils, Abhängigkeiten, Dokumentation usw. enthält).
  2. Installieren Sie nur die Binärdatei 'sleep.exe' und die erforderlichen Abhängigkeiten (verwenden Sie abhängige.exe, um Abhängigkeiten abzurufen).

Ein Vorteil der Bereitstellung von CoreUtils besteht darin, dass Sie zusätzlich eine Vielzahl anderer Programme erhalten, die für die Skripterstellung hilfreich sind (Windows-Batch lässt zu wünschen übrig).

Codesniffer
quelle