it-swarm.com.de

In einer Batchdatei schlafen

Beim Schreiben einer Batch-Datei zum Automatisieren von Objekten auf einer Windows-Box musste ich die Ausführung für einige Sekunden anhalten (normalerweise in einer Test-/Warteschleife und auf den Start eines Prozesses warten). Die beste Lösung, die ich finden konnte, verwendet zu dieser Zeit Ping (ich scheiß dich nicht), um den gewünschten Effekt zu erzielen. Ich habe eine bessere Beschreibung davon hier gefunden, die eine aufrufbare "wait.bat" beschreibt, die wie folgt implementiert wird:

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

Sie können Aufrufe von wait.bat dann in Ihre eigene Batchdatei aufnehmen und die Anzahl der Sekunden für den Ruhezustand übergeben.

Offensichtlich bietet das Windows 2003 Resource Kit einen Unix-ähnlichen Sleep-Befehl (endlich!). In der Zwischenzeit gibt es für diejenigen, die noch Windows XP, Windows 2000 oder (leider) Windows NT verwenden, einen besseren Weg?

Ich habe das sleep.py-Skript in der akzeptierten Antwort geändert, so dass es standardmäßig auf eine Sekunde eingestellt ist, wenn in der Befehlszeile keine Argumente übergeben werden:

import time, sys

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

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

import time, sys

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

Wenn dies erforderlich ist, werden Pausen in Sekundenschnelle zugelassen (z. B. 1,5 Sekunden, 0,1 Sekunden usw.). Wenn Sie es als sleep anstelle von sleep.py aufrufen möchten, können Sie die Erweiterung .PY zu Ihrer PATHEXT-Umgebungsvariablen hinzufügen. Unter Windows XP können Sie es bearbeiten in:

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

14
tzot

Der Befehl timeout 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 Umleitung von Eingaben - ein einfaches Beispiel:

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

Die ping-Methode wie beschrieben umreißt, wie ich es mache, wenn ich keine weiteren ausführbaren Dateien hinzufügen kann (möchte oder will) oder keine andere Software installieren möchte.

Sie sollten etwas pingen, das nicht vorhanden ist, und das -w-Flag verwenden, so dass es nach dieser Zeit fehlschlägt, und nicht etwas pingen, das ist dort (wie localhost) -n-mal. Dadurch können Sie weniger als eine Sekunde mit der Zeit umgehen, und ich denke, es ist etwas genauer.

z.B.

(Test, dass 1.1.1.1 nicht belegt ist)

ECHO Waiting 15 seconds

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

SLEEP.exe ist in den meisten Resource Kits enthalten, z. Das 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%)
15
Luk

Ich stimme den Antworten nicht zu, die ich hier gefunden habe.

Ich verwende die folgende Methode, die vollständig auf 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 Mitternacht überschreitet.

15
Aacini

Ich hatte ein ähnliches Problem, aber ich habe gerade eine sehr kurze C++ - Konsolenanwendung ausfindig gemacht, um dasselbe zu tun. Führen Sie einfach MySleep.exe 1000 - aus, vielleicht einfacher als das gesamte Ressourcenkit herunterzuladen/zu installieren.

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

Bei Server Fault, eine ähnliche Frage wurde gestellt , gab es folgende Lösung:

choice /d y /t 5 > nul
10
mlsteeves

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

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

Verwenden Sie abhängig von Ihren Kompatibilitätsanforderungen entweder ping:

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

z.B. mit 5 Sekunden warten 

ping -n 6 localhost >nul 2>&1

oder unter Windows 7 oder später verwenden Sie timeout:

timeout 6 >nul
8
Joey

Sie können Ping verwenden:

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

Es wird 10 Sekunden warten.

Der Grund für die Verwendung von 11 ist, dass der erste Ping sofort und nicht nach einer Sekunde ausgeht. Die Anzahl sollte immer um eins größer sein als die Anzahl Sekunden, die Sie warten möchten.

Denken Sie daran, dass der -w keine Sekunde warten soll. Es soll sichergestellt werden, dass Sie keine (mehr} _ als eine Sekunde warten, wenn Netzwerkprobleme auftreten. ping alleine sendet pro Sekunde ein ICMP-Paket. Für localhost ist dies wahrscheinlich nicht erforderlich, aber alte Gewohnheiten sind schwer zu ertragen.

8
paxdiablo
timeout /t <seconds> <options>

B. das Skript eine nicht unterbrechungsfreie Wartezeit von 2 Sekunden durchführen lassen:

timeout /t 2 /nobreak >NUL

Was bedeutet, dass das Skript 2 Sekunden wartet, bevor Sie fortfahren.

Standardmäßig unterbricht ein Tastendruck das Zeitlimit. Verwenden Sie den Schalter /nobreak, wenn der Benutzer die Wartezeit nicht unterbrechen (abbrechen) soll. Darüber hinaus gibt das Zeitlimit pro Sekunde Benachrichtigungen an, um den Benutzer zu benachrichtigen, wie lange noch gewartet werden muss. Dies kann entfernt werden, indem der Befehl an NUL übergeben wird.

edit: Da @martineauin den Kommentaren darauf hinweist, ist der Befehl timeout nur unter Windows 7 und höher verfügbar. Darüber hinaus verbraucht der Befehl ping weniger Prozessorzeit als timeout. Ich glaube immer noch daran, timeout zu verwenden, da dies besser lesbar ist als der ping-Hack. Lesen Sie mehr hier .

6
mgthomas99

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

192.0.2.0/24 - Dieser Block wird als "TEST-NET" zur Verwendung in .__ zugewiesen. Dokumentation und Beispielcode. Es wird oft in Verbindung mit .__ verwendet. Domänennamen example.com oder example.net in Anbieter und Protokoll Dokumentation. Adressen in diesem Block sollten nicht in der .__ erscheinen. öffentliches Internet.

Verwenden Sieping 192.0.2.1 -n 1 -w 123 >nul, um 123 Millisekunden zu schlafen.

5
mafu

Legen Sie dies einfach in Ihre Batchdatei, wo Sie warten möchten.

@ping 127.0.0.1 -n 11 -w 1000 > null
5
Brent Stewart

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,.

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

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

powershell -command "Start-Sleep -s 1"

Edit: from meine Antwort auf einen ähnlichen Thread , die Leute haben ein Problem angesprochen, bei dem die Zeit, die Powershell benötigt, um zu beginnen ist, verglichen mit der Wartezeit, auf die Sie warten. Wenn die Genauigkeit der Wartezeit wichtig ist (dh eine oder zwei zusätzliche Verzögerungen sind nicht akzeptabel), 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 die Zeit, zu der der Windows-Befehl ausgegeben wurde, und das Powershell-Skript ist bis 5 Sekunden nach dieser Zeit inaktiv. Solange Powershell weniger Zeit zum Starten benötigt als Ihre Schlafdauer, funktioniert dieser Ansatz (auf meinem Computer sind es etwa 600 ms).

4

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

Das Cygwin-Paket enthält außerdem eine sleep-plop-Datei, die in Ihren PFAD eingefügt wird, und den cygwin.dll (oder wie auch immer er genannt wird) und den Weg, den Sie benötigen, enthalten.

4
Daren Thomas

Ich mag Aacinis Antwort . Ich fügte hinzu, um den Tag zu handhaben und es auch zu ermöglichen, centiseconds (%TIME% Ausgaben H:MM:SS.CC) zu handhaben:

: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
Hossy

Ich habe dieses C # -Schlafprogramm verwendet. Es könnte für Sie bequemer sein, 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");
            }
        }
    }
}
3
Liam

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

timeout numbersofseconds /nobreak > nul
2
Tato

Die Verwendung von ping ist gut, solange Sie nur "etwas warten" möchten. Dies ist erforderlich, da Sie auf andere Funktionen darunter angewiesen sind, z. B. auf das Funktionieren Ihres Netzwerks und auf die Tatsache, dass auf 127.0.0.1 keine Antwort vorliegt. ;-) Vielleicht ist es nicht sehr wahrscheinlich, dass es fehlschlägt, aber es ist nicht unmöglich ... 

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

Das Finden einer bereits erstellten ausführbaren Datei für den Schlaf ist der bequemste Weg. Legen Sie es einfach in Ihrem Windows-Ordner oder einem anderen Teil Ihres Standardpfads ab und es ist immer verfügbar.

Andernfalls können Sie in kompilierten Umgebungen leicht selbst eine erstellen. Die Sleep-Funktion ist in kernel32.dll verfügbar, sodass Sie nur diese verwenden müssen. : -) Für VB/VBA erklären 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 Funktion (seit Windows 2000 verfügbar) finden Sie unter Sleep-Funktion (MSDN).

In Standard C ist sleep() in der Standardbibliothek enthalten. In Visual Studio C von Microsoft heißt die Funktion Sleep(), wenn der Speicher verfügbar ist. ;-) Diese beiden nehmen das Argument in Sekunden, nicht in Millisekunden wie die beiden vorherigen Erklärungen.

2
Tooony

Noch leichter als die Python-Lösung ist ein Einliner von Perl

Um sieben Sekunden lang zu schlafen, fügen 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 Modul Time :: HiRes Von CPAN. Es liefert usleep(), die in __. Mikrosekunden schläft, und nanosleep(), die in Nanosekunden __ schläft (beide Funktionen akzeptieren nur ganzzahlige Argumente). Siehe die Stack Overflow-Frage Wie schlafe ich eine Millisekunde in Perl? für weitere Details.

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

2
Peter Mortensen

Oder Befehlszeile Python zum Beispiel für 6,5 Sekunden:

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

Ich bin beeindruckt von diesem:

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

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

Technisch sagen Sie dem Befehl choice, nur y zu akzeptieren. Der Standardwert ist y, um dies in 5 Sekunden zu tun, keine Eingabeaufforderung zu zeichnen und alles, was es sagt, an NUL zu übergeben (wie ein Nullterminal unter Linux).

1
Chris Moschini

Unter Windows Vista verfügen Sie über die Befehle TIMEOUT und SLEEP . Wenn Sie sie jedoch unter Windows XP oder Windows Server 2003 verwenden möchten, benötigen Sie das Ressourcen-Toolkit Windows Server 2003 .

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 genannten, der (ab) den W32TM (Zeitdienst) Befehl:

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

Wo sollen Sie das N durch die Sekunden ersetzen, die Sie anhalten möchten. Es funktioniert auch auf jedem Windows-System ohne Voraussetzungen.

Typeperf kann auch verwendet werden:

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

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
1
Andry

Sie können auch eine VBS-Datei verwenden, um bestimmte Timeouts auszuführen:

Der folgende Code erstellt die VBS-Datei. Fügen Sie diesen in der Nähe Ihres Rbatch-Codes 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 beliebig lang ändern.

Der folgende Code löscht die VBS-Datei, nachdem Sie damit fertig sind. Setzen Sie dies am Ende Ihrer Batchdatei:

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

Und hier ist der Code alle zusammen, so dass es einfach ist zu kopieren:

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

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

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 "sleep.exe" - Binärdatei und die erforderlichen Abhängigkeiten (verwenden Sie zum Erstellen von Abhängigkeiten die Abhängesystem.exe).

Ein Vorteil der Bereitstellung von CoreUtils ist, dass Sie zusätzlich einen Host mit anderen Programmen erhalten, die für das Scripting hilfreich sind (Windows-Stapelverarbeitung lässt zu wünschen übrig).

0
codesniffer

Sie können Lust bekommen, 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
0
djangofan

Dies wurde unter Windows XP SP3 und Windows 7 getestet und verwendet CScript. Ich habe einige sichere Wächter eingesetzt, um die Aufforderung zu vermeiden. (/q wäre gefährlich)

Warte eine Sekunde:

sleepOrDelayExecution 1000

Warten Sie 500 ms und führen Sie dann folgende 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
0