Wie schlafen Sie in einer Batch-Datei?

132

Wie pausiere ich die Ausführung in einer Windows-Batchdatei zwischen einem Befehl und dem nächsten?

Massimo
quelle
Soll dies eine kanonische werden? In diesem Fall ist möglicherweise ein erläuternder Text angebracht.
John Gardeniers
2
"Erläuterungstext" wie in?
Massimo,
2
Die meisten, wenn nicht alle kanonischen Fragen, die ich gesehen habe, enthalten Text, der die Absicht dieser Frage beschreibt.
John Gardeniers
Oder ein Text, der die Situation erklärt ... Er dient hauptsächlich der Hilfe bei der Suchmaschinenoptimierung, hilft aber auch bei der Festlegung möglicher Antworten.
Chris S
2
SEO funktioniert gut. Erster Treffer für mich bei der Google-Suche.
jbo5112

Antworten:

194

Die richtige Art, in einer Batch-Datei zu schlafen, ist die Verwendung des timeoutin Windows 2000 eingeführten Befehls.

So warten Sie zwischen 29 und 30 Sekunden :

timeout /t 30

Das Timeout würde unterbrochen, wenn der Benutzer eine Taste drückt. Der Befehl akzeptiert jedoch auch den optionalen Schalter /nobreak, der alles ignoriert, was der Benutzer drücken kann, mit Ausnahme eines expliziten Befehls CTRL-C:

timeout /t 30 /nobreak

Wenn Sie nicht möchten, dass der Befehl den Countdown auf dem Bildschirm ausgibt, können Sie die Ausgabe umleiten an NUL:

timeout /t 30 /nobreak > NUL
Massimo
quelle
6
Der Befehl timeout funktioniert nicht unter Windows XP, auch wenn das Resource Kit 2003 installiert ist, und der Befehl sleep funktioniert nicht unter Windows 7, sodass der Befehl ping weiterhin nützlich sein kann, wenn Sie die Batchdatei sowohl unter Win7 als auch unter WinXP verwenden.
12
In nicht interaktiven Skripten funktioniert das Zeitlimit nicht: "FEHLER: Die Eingabeumleitung wird nicht unterstützt und der Prozess wird sofort beendet." manchmal wird hack mit "ping" bevorzugt.
iMysak
14

Da es auch hier gilt, kopiere ich meine Antwort von einer anderen Seite .

Wenn Sie Ping verwenden möchten, gibt es einen besseren Weg. Sie möchten eine Adresse anpingen, die nicht vorhanden ist, damit Sie eine Zeitüberschreitung mit Millisekundengenauigkeit angeben können. Glücklicherweise ist eine solche Adresse in einem Standard (RFC 3330) definiert, und das ist es auch 192.0.2.x. Dies ist nicht erfunden, es ist wirklich eine Adresse mit dem einzigen 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 der Dokumentation und im Beispielcode zugewiesen. Es wird häufig in Verbindung mit Domainnamen example.com oder example.net in der Hersteller- und Protokolldokumentation verwendet. Adressen innerhalb dieses Blocks sollten nicht im öffentlichen Internet erscheinen.

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

Mafu
quelle
3
Tun Sie das bitte nicht, auch wenn es etwas besser ist, als eine echte Adresse anzupingen. Pingist einfach das falsche Werkzeug für den Job.
Massimo
1
@ Massimo Es ist höchstwahrscheinlich nicht das, wofür es gedacht war :) Aber ich denke, es ist immer noch eine gute Lösung - es funktioniert in einigen Szenarien besser als Timeout (insbesondere bei höherer Auflösung). Es ist auch ziemlich bekannt geworden, so dass die meisten Leute nicht sehr überrascht (dh verwirrt) wären, wenn sie es in Ihrer Batch-Datei sehen.
Mafu
2
@ Massimo In Ordnung! Ich denke, wir haben nur unterschiedliche Ansichten. Wenn es Ihnen nichts ausmacht, lasse ich diese Antwort trotzdem offen, da es anscheinend besser ist, localhost n-mal anzupingen, wie dies am häufigsten beschrieben wird.
Mafu
7
timeout ist die richtige Lösung für die Betriebssysteme, auf denen es funktioniert. ping ist die einzige Lösung, die von 5.1-6.3 funktioniert. Bei 25% der Systeme, die noch mit 5.1 arbeiten, ist das Timeout nicht "der richtige Weg".
Wyrmwood
3
timeout ist für jedes Betriebssystem die falsche Lösung, da es selbst unter Windows 10 tödlich funktioniert. Was nützt ein Befehl, der nur deshalb fehlschlägt, weil Eingaben umgeleitet werden?
Harry Johnston
8

Sie können auch einen Ping an localhost einfügen. Dies dauert 4 Sekunden (standardmäßig). Es wird von manchen als Kludge angesehen, funktioniert aber trotzdem ganz gut.

Der Befehl:
ping 127.0.0.1

Akolyth
quelle
6
Ehm ... der ganze Zweck dieses Q / A war genau , zwei andere Fragen zu korrigieren, die dies als ihre akzeptierte Antwort haben, aber nicht mehr korrigiert werden können, weil ihr OP nicht mehr da ist.
Massimo
6
Während es funktioniert, entspricht es dem Einschlagen einer Schraube mit einem Hammer. Ein falsches Werkzeug mag funktionieren, aber es ist immer noch falsch.
Voretaq7
1
@ MarkAllen Mit anderen Worten, Windows NT4, 95, 98, ME und älter?
Chris McKeown
5
@MarkAllen - technisch gesehen müssen Sie sich dann Gedanken machen, ob pingIhr Betriebssystem mitgeliefert wird oder nicht . Wenn Sie genug über '95 '98 oder ME besorgt sind , dann sollten Sie als gleichermaßen besorgt über 6,22 sein , was nicht hat pingentweder
Mark Henderson
4
@MarkHenderson Es ist (für mich) einfacher, sich daran zu erinnern, ob eine bestimmte Version des Betriebssystems TCP / IP unterstützt, als sich daran zu erinnern, ob sie einen Befehl enthält, den ich zuvor noch nicht gehört hatte. Wissen Sie?
Mark Allen
2

Disclaimer : dies ist nicht die „ideale“ Lösung, so nicht die Mühe , mich über den Kopf schlägt mit dieser wie denjenigen getan zu empfehlen ping...

Verwenden Sie wenn möglich timeoutauf jeden Fall. Wie in den Kommentaren erwähnt, ist dies jedoch nicht immer eine Option (z. B. im nicht interaktiven Modus). Danach stimme ich zu, dass der ping"Kludge" die nächstbeste Option ist, da er sehr einfach ist. Das heißt, ich biete eine andere Option an ... binde ein paar VB-Skripte ein .

Die Basis dieser Lösung ist darüber hinaus vielseitig einsetzbar. Oft kann VBS Dinge tun, die Batch nicht können, oder zumindest drastisch einfacher. Mit der hier abgebildeten Technik können Sie beides mischen (nicht "nahtlos", sondern "funktional" ...).

Hier ist ein Einzeiler, um ein temporäres Skript zu erstellen, es auszuführen und dann zu löschen. Das Skript erledigt den Ruhezustand für Sie (in diesem Beispiel für 3 Sekunden).

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

Hier ist im Grunde das Gleiche, etwas anders geschrieben:

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

Und dann schließlich, wie ping, CScriptselbst hat eine Timeout - Option! Wenn Sie also eine Endlosschleife im Skript eingeben, können Sie den Interpreter die Dauer erzwingen lassen. Beachten Sie, dass dies ein "ausgelasteter" Vorgang ist, der die CPU belastet, und daher empfehle ich ihn nicht, wenn Sie die WScript.SleepProzedur verwenden können, aber der Vollständigkeit halber stelle ich ihn als konzeptionelle Option vor:

set sleepSec=3 & set sleepVbs=%temp%\sleep.vbs & echo While True > %sleepVbs% & echo Wend >> %sleepVbs% & cscript %sleepVbs% //B //T:%sleepSec% & del %sleepVbs%
BuvinJ
quelle
Weißt du ... du könntest das in Powershell machen, ohne eine Datei schreiben zu müssen.
Harry Johnston
Ja, das ist wahrscheinlich eine weitere gute Lösung, obwohl diese meiner Meinung nach abwärtskompatibler mit alten Windows-Versionen ist.
BuvinJ