Spanie w pliku wsadowym

150

Podczas pisania pliku wsadowego w celu zautomatyzowania czegoś na komputerze z systemem Windows musiałem wstrzymać jego wykonanie na kilka sekund (zwykle w pętli test / czekanie, czekając na rozpoczęcie procesu). W tamtym czasie najlepszym rozwiązaniem, jakie znalazłem, jest ping (nie żartuję), aby osiągnąć pożądany efekt. Znalazłem tutaj lepszy opis tego , który opisuje wywoływany plik „wait.bat”, zaimplementowany w następujący sposób:

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

Następnie możesz zawrzeć wywołania wait.bat we własnym pliku wsadowym, przekazując liczbę sekund uśpienia.

Najwyraźniej zestaw Windows 2003 Resource Kit zawiera polecenie usypiania podobne do uniksowego (w końcu!). W międzyczasie, dla tych z nas, którzy nadal używają Windows XP, Windows 2000 lub (niestety) Windows NT , czy istnieje lepszy sposób?

Zmodyfikowałem sleep.pyskrypt w akceptowanej odpowiedzi , aby domyślnie ustawiał jedną sekundę, jeśli w linii poleceń nie są przekazywane żadne argumenty:

import time, sys

time.sleep(float(sys.argv[1]) if len(sys.argv) > 1 else 1)
Jason Etheridge
źródło
Strona pobierania Microsoft Windows 2003 Resource Kit wskazuje, że działa on również w systemie XP. Obawiam się, że nie ma innego wyjścia, jak tylko użyć „zewnętrznego” narzędzia do czekania: nic takiego nie jest wbudowane w procesor poleceń XP.
GerG,
Zestaw zasobów serwera 2003 działa z systemem Windows XP (i prawdopodobnie z w2k)
Martin Beckett
W przeszłości spotkałem się z tym samym problemem i sam użyłem pinga (z uwagą powyżej wyraźnie dokumentującą, że zdaję sobie sprawę, że to głupie :)).
Jack Leow,
2
Masz kilka opcji - emuluj tryb uśpienia za pomocą pingpolecenia lub pobierz zestaw zasobów systemu Windows, który zawiera sleeppolecenie. Więcej szczegółów tutaj: Plik wsadowy SLEEP Command
Rudu

Odpowiedzi:

14

AKTUALIZACJA

timeoutPolecenia, dostępny z systemem Windows Vista i dalej należy stosować polecenie, jak opisano w innej odpowiedzi na to pytanie. Poniżej znajduje się stara odpowiedź.

Stara odpowiedź

Jeśli masz zainstalowany Python lub nie masz nic przeciwko zainstalowaniu go (ma też inne zastosowania :), po prostu utwórz następujący skrypt sleep.py i dodaj go gdzieś w swojej PATH:

import time, sys

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

Pozwoli to na przerwy poniżej sekundy (na przykład 1,5 sek., 0,1 itd.), Jeśli zajdzie taka potrzeba. Jeśli chcesz nazwać to sleepraczej niż sleep.py, możesz dodać .PYrozszerzenie do zmiennej środowiskowej PATHEXT. W systemie Windows XP możesz go edytować w:

Mój komputer → Właściwości (menu) → Zaawansowane (zakładka) → Zmienne środowiskowe (przycisk) → Zmienne systemowe (ramka)

tzot
źródło
32
dlaczego mielibyśmy pisać skrypt w Pythonie, gdy wymagane jest rozwiązanie wsadowe? W jaki sposób rozszerzenie ścieżki może rozwiązać problem polegający na tym, że użytkownicy systemu Windows nie mają zainstalowanego interpretera języka Python? Dzięki.
Val
6
Ze względu na przenośność uważam, że należy unikać tego rozwiązania, ponieważ istnieją doskonałe, natywne alternatywy.
Gras Double
1
To podejście mogło dawać obejście tego problemu w przeszłości, ale natywne rozwiązanie opisane przez @Blorgbeard jest zdecydowanie właściwą drogą.
Mike
227

timeoutKomenda jest dostępna począwszy od systemu Windows Vista:

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

Uwaga: nie działa z przekierowaniem danych wejściowych - trywialny przykład:

C:\>echo 1 | timeout /t 1 /nobreak
ERROR: Input redirection is not supported, exiting the process immediately.
Blorgbeard wyszedł
źródło
8
nie działa w zastosowaniach bez konsoli: „BŁĄD: przekierowanie danych wejściowych nie jest obsługiwane, natychmiastowe zakończenie procesu”.
simpleuser
Miałem na myśli przypadki, w których w ogóle nie masz konsoli, na przykład gdy plik wsadowy jest uruchamiany w tle przez fork z innego procesu, cygwin crontab lub zdalne polecenie ssh itp.
simpleuser
1
O tak, wiem. Przykład, który podałem, miał na celu zademonstrowanie błędu :)
Blorgbeard wychodzi
3
Link do dokumentacji timeout, dodane przez @Cristian Ciupitu, jest częściowo błędne - Windows XP nie posiada tej komendy.
martineau
1
@HelloWorld, który brzmi jak problem z Twoim% PATH%
Blorgbeard jest dostępny
21

Używając pingopisanej metody, robię to, gdy nie mogę (lub nie chcę) dodawać więcej plików wykonywalnych lub instalować innego oprogramowania.

Powinieneś pingować coś, czego nie ma, i używać -wflagi, aby po tym czasie nie powiodło się, a nie pingować razy coś, co tam jest (na przykład localhost) -n. Pozwala to na obsługę czasu krótszego niż sekunda i myślę, że jest to nieco dokładniejsze.

na przykład

(sprawdź, czy wersja 1.1.1.1 nie została podjęta)

ECHO Waiting 15 seconds

PING 1.1.1.1 -n 1 -w 15000 > NUL
  or
PING -n 15 -w 1000 127.1 >NUL
daniel
źródło
Natychmiast wraca zPING: transmit failed. General failure.
huysentruitw
IP 1.1.1.1jest pobierane przez CloudFlare, więc nie będzie to czekać 15 sekund, ale około kilku ms.
dhcgn
16

SLEEP.exejest częścią większości zestawów zasobów, np . zestawu Windows Server 2003 Resource Kit, który można zainstalować również w systemie Windows XP.

Usage:  sleep      time-to-sleep-in-seconds
        sleep [-m] time-to-sleep-in-milliseconds
        sleep [-c] commited-memory ratio (1%-100%)
Luk
źródło
15

Nie zgadzam się z odpowiedziami, które tutaj znalazłem.

Używam następującej metody całkowicie opartej na możliwościach systemu Windows XP, aby zrobić opóźnienie w pliku wsadowym:

OPÓŹNIENIE 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

Możesz również wstawić dzień do obliczenia, aby metoda działała również wtedy, gdy interwał opóźnienia przekroczy północ.

Aacini
źródło
15
Powinno to być dokładne, ale wymaga to dużej mocy obliczeniowej. Zwykle potrzebujesz implementacji sterowanej przerwaniem, aby proces nie zużywał cykli procesora podczas oczekiwania. Nie powinno to stanowić problemu przy rzadkich krótkich oczekiwaniach, jak to jest prawdopodobnie w przypadku większości sytuacji wsadowych. Jednak ciągły proces z długimi oczekiwaniami może mieć negatywny wpływ na wydajność systemu.
dbenham
4
Ponieważ używa zegara systemowego, dokładność wynosi jedną sekundę. Jeśli określono 2 sekundy, opóźnienie może wynosić od 2 do 3 sekund (w rzeczywistości 2,99999 ... sekund).
Peter Mortensen
A co jeśli jest teraz 7:59:59, a chcesz poczekać 7 sekund? Wygląda na to, że nie bierze tego pod uwagę.
popiół 999
Zużywa to więcej czasu procesora niż liczy czas systemowy. Ponadto wykonujesz operacje arytmetyczne na liczbach ósemkowych, ponieważ minuty i sekundy mniejsze niż 10 są wyświetlane z początkowym 0 w TIMEpoleceniu.
Andreas
2
@mrt: Problem polega na tym, że %TIME%do oddzielenia centisekund zamiast kropki używasz przecinka! Po prostu dodaj przecinek w DELIMS=:.,"...
Aacini
13

Miałem podobny problem, ale właśnie uruchomiłem bardzo krótką aplikację konsolową C ++, aby zrobić to samo. Po prostu uruchom MySleep.exe 1000 - być może łatwiejsze niż pobranie / zainstalowanie całego zestawu zasobów.

#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
źródło
10

W przypadku błędu serwera zadano podobne pytanie , a rozwiązanie było:

choice /d y /t 5 > nul
mlsteeves
źródło
7
FYI: Choice nie jest uwzględniony w systemie Windows XP. Był w systemie Windows 9x, usunięty z XP i dodany z powrotem w systemie Vista.
Devin Burke
7
W ogóle tego nie polecam. Przynajmniej we wszystkich CHOICEwersjach, które znam, jeśli ktoś w oczekiwaniu naciśnie przycisk, co czasami robią niecierpliwi ludzie, to wybór zarejestruje wejście, wyda sygnał dźwiękowy systemu dla złego wejścia i zatrzyma licznik czasu, co oznacza, że ​​się zawiesi tam, chyba że nacisną N lub Y. A jeśli zdarzy się, że wcisną jedno z tych dwóch, wybór kończy się właśnie w tym miejscu, zamiast czekać na 5. Poza tym ten wybór wykorzystuje naprawdę dziwną składnię Visty. Zamiast tego używałyby CHOICE /T:Y,5 > NULdo tego wszystkie zwykłe polecenia wyboru . W /Dstarszych wersjach nie ma flagi.
Kodowanie ze stylem
1
Co więcej, przynajmniej polecenia CHOICE, które znam, mają różne domyślne przyciski tak / nie w zależności od języka, w którym przyszedł, więc jeśli zdarzy ci się polegać na domyślnym wyborze [T, N] zamiast jawnie określać go za pomocą /C:YNlub po prostu /C:Y, to nie zadziała, jeśli ktoś ma, powiedzmy, szwedzką komendę wyboru, która prawdopodobnie domyślnie wykona [J, N]. Więc to jest pogrążone w różnego rodzaju kłopotach.
Kodowanie ze stylem,
1
@Kodowanie Przetestowano to w Win7 i jeśli użytkownik naciśnie przycisk, wyda sygnał dźwiękowy, jednak po dodatkowych 5 sekundach po naciśnięciu przycisku przez użytkownika będzie nadal upływać limit czasu. Więc jeśli użytkownik będzie naciskać klawisze, nigdy nie przekroczy limitu czasu. Również w moim przypadku, gdy z tego korzystałem, uważam, że ukrywa konsolę, aby użytkownik nie mógł nacisnąć przycisku. W tym systemie nie było dostępu do Pythona, nie było możliwości upuszczenia własnego exe w systemie (jak sugerowano w innych odpowiedziach), byłem dość ograniczony w tym, co mogłem zrobić. Więc co byś polecił?
mlsteeves
@mlsteeves Każdy inny system Windows, DOS itp. ma inne polecenie wyboru i jak zauważono, nie jest ono normalnie dostępne w Xp. Wiele poleceń wyboru ma nieco inne zachowanie, a niektóre mają nawet inną składnię. Ja generalnie używam polecenia ping, kiedy potrzebuję snu. Jest brzydki, ale niezawodny.
Kodowanie w stylu
9

Możesz użyć warstwy WSH cscript systemu Windows i tego pliku JavaScript wait.js :

if (WScript.Arguments.Count() == 1)
    WScript.Sleep(WScript.Arguments(0)*1000);
else
    WScript.Echo("Usage: cscript wait.js seconds");
Blake7
źródło
1
Host skryptów systemu Windows można jednak wyłączyć za pomocą zasad grupy.
Joey
8

W zależności od potrzeb dotyczących zgodności użyj ping:

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

np. odczekać 5 sekund, użyć

ping -n 6 localhost >nul 2>&1

lub w systemie Windows 7 lub nowszym użyj timeout:

timeout 6 >nul
Joey
źródło
2
-wjest w milisekundach, -nto po prostu liczba wykonań polecenia ping, a domyślny czas między pingami to sekunda.
Joey,
8

Możesz użyć ping:

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

Poczeka 10 sekund.

Powodem, dla którego musisz użyć 11, jest to, że pierwszy ping znika natychmiast, a nie po jednej sekundzie. Liczba powinna zawsze być o jeden większa niż liczba sekund, które chcesz czekać.

Pamiętaj, że celem tego -wnie jest czekanie ani sekundy. Ma to na celu zapewnienie, że nie będziesz czekać dłużej niż jedną sekundę w przypadku problemów z siecią. pingsamodzielnie wysyła jeden pakiet ICMP na sekundę. Prawdopodobnie nie jest to wymagane w przypadku hosta lokalnego, ale stare nawyki ciężko umierają.

paxdiablo
źródło
nie zaleca się używania tego do krytycznego przetwarzania w czasie rzeczywistym. ponieważ używana jest komenda PING, możliwe jest, że ten plik wsadowy WAIT może działać przez kilka milisekund
Wael Dalloul,
12
@Wael, jeśli mówisz o czekaniu na jednosekundowe granice, kilka milisekund nie będzie miało znaczenia. A jeśli używasz cmd.exe do rzeczy w czasie rzeczywistym, zasługujesz na wszystko, co dostajesz :-)
paxdiablo
-w to wartość limitu czasu. Jest to liczba milisekund oczekiwania na odpowiedź ... a nie czas oczekiwania między pingami.
quux
@quux, nigdzie nie stwierdziłem, że upłynął -wlimit czasu (chociaż przyznaję, że niektórzy mogą wywnioskować, że z powodu mojego braku jasności), w rzeczywistości jest używany do ograniczenia czasu cyklu, w którym występują problemy z siecią, które spowodowałyby, że każdy cykl zająłby więcej niż przydzielony druga. Dodałem akapit na końcu, aby to wyjaśnić.
paxdiablo
Problem polega na tym, że jeśli pingi wracają szybciej , możesz nie czekać pełną sekundę między pingami. więc twoja pętla oczekiwania zakończy się szybciej, niż się spodziewałeś
quux
7

Jest lepszy sposób na spanie za pomocą pinga. Będziesz chciał pingować adres, który nie istnieje, więc możesz określić limit czasu z dokładnością do milisekund. Na szczęście taki adres jest zdefiniowany w standardzie (RFC 3330) i tak jest 192.0.2.x. To nie jest zmyślone, to naprawdę jest adres, którego jedynym celem jest nieistnienie (może nie być jasne, ale dotyczy to nawet w sieciach lokalnych):

192.0.2.0/24 - Ten blok jest przypisany jako „TEST-NET” do użytku w dokumentacji i przykładowym kodzie. Jest często używany w połączeniu z nazwami domen example.com lub example.net w dokumentacji dostawcy i protokołu. Adresy w tym bloku nie powinny pojawiać się w publicznym Internecie.

Aby spać przez 123 milisekundy, użyj ping 192.0.2.1 -n 1 -w 123 >nul

mafu
źródło
Tak, jest to łatwiejsze do napisania i zrozumienia niż konieczność dodawania jednego do -nparametru.
Peter Mortensen
Jednak zmierzyłem to (używając 100 pingów). Jeśli użyję -n 3 -w 124, rzeczywisty czas wynosi dokładnie (3 + 1) * (124 + 1) = 4 * 125 = 500 ms. Czas jest zaskakująco stabilny, z dokładnością do rozdzielczości 10 ms podczas odczytu (przez monit CMD z czasem) - a podstawowa rozdzielczość jest zdecydowanie lepsza niż 10 ms (nie ma na nią wpływu zwykła rozdzielczość taktu 16 ms).
Peter Mortensen
@mafu To, że adres 192.0.2.0/24 nie powinien być używany, nie oznacza, że ​​nie można go użyć, a zatem nie ma gwarancji, że nie ma odpowiedzi na żądanie (-a) echa. Na przykład skonfiguruj dla dowolnego komputera z systemem Windows statyczny adres IPv4 192.0.2.1 i maskę podsieci 255.255.255.0 i podłącz kartę sieciową do dowolnego innego urządzenia. Wystarczy prosty włącznik, do którego nic innego nie jest podłączone. Następnie uruchom ping 192.0.2.1na tym komputerze z systemem Windows i widać, że stos TCP / IP systemu Windows odpowiada na żądania echa. Ile osób wie, że adres 192.0.2.0/24 nie powinien być używany jako statyczny adres IPv4?
Mofi,
1
Per dyskusji w komentarzach tutaj wydaje się, że 192.0.2.1 nie jest tak niezawodny i niektórzy sugerują, że 127.255.255.255 jest lepszym wyborem. Myśli?
JLRishe
Komentarze wspomniane w powyższym poście zostały teraz usunięte (prawdopodobnie jako NLN), ale zgodziłbym się na zmianę ze 127.255.255.255względu na to, że jest to adres transmisji zwrotnej w systemie Windows, który jest już domyślnie przypisany (możesz to potwierdzić uruchamiając route printw cmd i przeglądając tablicę tras IPv4, którą drukuje).
Hoppeduppeanut
6

Jeśli masz PowerShell w swoim systemie, możesz po prostu wykonać to polecenie:

powershell -command "Start-Sleep -s 1"

Edycja: z mojej odpowiedzi w podobnym wątku ludzie podnieśli problem, w którym czas potrzebny do uruchomienia PowerShell jest znaczący w porównaniu z tym, jak długo próbujesz czekać. Jeśli dokładność czasu oczekiwania jest ważna (np. Sekunda lub dwie dodatkowe opóźnienia są niedopuszczalne), możesz zastosować następujące podejście:

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

Zajmuje to czas, gdy polecenie systemu Windows zostało wydane, a skrypt PowerShell pozostaje w stanie uśpienia do 5 sekund po tym czasie. Tak długo, jak uruchomienie programu PowerShell zajmuje mniej czasu niż czas snu, takie podejście będzie działać (na moim komputerze jest to około 600 ms).

Niall Connaughton
źródło
6
timeout /t <seconds> <options>

Na przykład, aby skrypt wykonywał nieprzerywalne 2-sekundowe oczekiwanie:

timeout /t 2 /nobreak >NUL

Oznacza to, że skrypt będzie czekał 2 sekundy przed kontynuowaniem.

Domyślnie naciśnięcie klawisza przerwie limit czasu, więc użyj /nobreakprzełącznika, jeśli nie chcesz, aby użytkownik mógł przerwać (anulować) oczekiwanie. Ponadto limit czasu zapewni powiadomienia na sekundę, aby powiadomić użytkownika, jak długo ma czekać; można to usunąć, przesyłając polecenie potokiem do NUL.

edycja: jak @martineau wskazuje w komentarzach , timeoutpolecenie jest dostępne tylko w systemie Windows 7 i nowszych. Ponadto pingpolecenie zużywa mniej czasu procesora niż timeout. Nadal jednak wierzę w używanie go timeouttam, gdzie to możliwe, ponieważ jest bardziej czytelny niż ping„hack”. Przeczytaj więcej tutaj .

mgthomas99
źródło
2
Najwyraźniej to polecenie jest dostępne tylko w systemie Windows 7/2008 i zestawie zasobów XP (i prawdopodobnie 8 / 8.1). Źródło twierdzi również, że pingpodejście to zużywa mniej czasu procesora.
martineau
5

Po prostu umieść to w pliku wsadowym tam, gdzie chcesz poczekać.

@ping 127.0.0.1 -n 11 -w 1000 > null
Brent Stewart
źródło
Czym to się różni od odpowiedzi paxdiablo?
Peter Mortensen
2
Nie jest inaczej, ale odpowiedzi tutaj pochodzą z wielu połączonych pytań, więc nie wszystkie odpowiedzi istniały, gdy odpowiadałem.
Brent Stewart
4

W Notatniku napisz:

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

Teraz zapisz jako wait.bat w folderze C: \ WINDOWS \ System32, a następnie, gdy chcesz czekać, użyj:

CALL WAIT.bat <whole number of seconds without quotes>
SuperKael
źródło
Pinguje się wielokrotnie, czekając sekundę między każdym pingiem, a następnie powraca do programu wywołującego, nie widzę nieskończonej pętli, ale sam to przetestowałem.
SuperKael
Mój błąd, nie ma nieskończonej pętli. Jednak, jak wspomniano w jednej z pozostałych odpowiedzi , lepiej zrobić pingcoś nie tylko raz i użyć -w Timeoutopcji dla czasu opóźnienia w milisekundach, a nie opcji -n Countcałkowitej liczby ponownych prób.
martineau
-w Timeoutmoże być lepsze, ale upewniłem się, że pinguje jeszcze raz niż podany czas.
SuperKael
4

Resource Kit zawsze włączone to. Przynajmniej od Windows 2000.

Ponadto pakiet Cygwin zawiera sleep- włóż to do swojej ŚCIEŻKI i dołącz cygwin.dll(lub jakkolwiek to się nazywa) i sposób!

Daren Thomas
źródło
2
Zauważ, że cygwin1.dll nie współistnieje pokojowo z różnymi wersjami samego siebie. Lepiej mieć jeden i tylko jeden plik cygwin1.dll na swoim komputerze, w przeciwnym razie będziesz miał dziwne awarie.
JesperE
Który zestaw zasobów? Wydaje się, że jest więcej niż jeden. Czy możesz zaktualizować swoją odpowiedź?
Peter Mortensen
3

Podoba mi się odpowiedź Aaciniego . Dodałem do tego, aby obsługiwać dzień, a także włączać obsługę centisekund ( %TIME%wyjścia 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
Hossy
źródło
3

Używam tego programu do snu w języku C #. Może być wygodniej, jeśli preferujesz język C #:

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
źródło
3

Jeszcze lżejszy niż rozwiązanie w Pythonie jest jednolinijkowy Perl.

Aby spać na siedem sekund, umieść to w skrypcie BAT:

perl -e "sleep 7"

To rozwiązanie zapewnia rozdzielczość tylko jednej sekundy.

Jeśli potrzebujesz wyższej rozdzielczości, użyj modułu Time :: HiRes firmy CPAN. Podaje, usleep()który śpi w mikrosekundach, a nanosleep()który w nanosekundach (obie funkcje przyjmują tylko argumenty całkowite). Zobacz pytanie o przepełnienie stosu Jak przespać milisekundę w Perlu? dla dalszych szczegółów.

Korzystam z ActivePerl od wielu lat. Jest bardzo łatwy w montażu.

Peter Mortensen
źródło
2

Lub na przykład Python z wiersza poleceń przez 6 i pół sekundy:

python -c "import time;time.sleep(6.5)"
Alex Robinson
źródło
Chociaż krócej, jest to duplikat zaakceptowanej odpowiedzi.
Peter Mortensen
@Peter Mortensen: Pozwala również łatwo umieścić wszystko w jednym wierszu pliku wsadowego.
martineau
2

Użycie polecenia ping jest dobre, o ile chcesz tylko „chwilę poczekać”. Dzieje się tak, ponieważ jesteś zależny od innych funkcji pod spodem, takich jak praca sieci i fakt, że nic nie odpowiada na 127.0.0.1. ;-) Może mało prawdopodobne, że się nie uda, ale nie jest to niemożliwe ...

Jeśli chcesz mieć pewność, że czekasz dokładnie przez określony czas, powinieneś skorzystać z sleepfunkcji (która ma również tę zaletę, że nie zużywa mocy procesora ani nie czeka, aż sieć będzie gotowa).

Najwygodniejszym sposobem jest znalezienie już utworzonego pliku wykonywalnego do uśpienia. Po prostu upuść go do folderu Windows lub dowolnej innej części standardowej ścieżki i jest zawsze dostępny.

W przeciwnym razie, jeśli masz środowisko kompilacyjne, możesz je łatwo stworzyć samodzielnie. Ta Sleepfunkcja jest dostępna w programie kernel32.dll, więc wystarczy jej użyć. :-) Dla VB / VBA zadeklaruj na początku źródła, co następuje, aby zadeklarować funkcję uśpienia:

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

Dla C #:

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

Więcej informacji na temat tej funkcji (dostępnej od Windows 2000) w funkcji uśpienia (MSDN) znajdziesz tutaj.

W standardowym C sleep()jest zawarta w bibliotece standardowej, aw Visual Studio C firmy Microsoft funkcja nosi nazwę Sleep(), jeśli pamięć mi służy. ;-) Te dwa przyjmują argument w sekundach, a nie w milisekundach, jak dwie poprzednie deklaracje.

Tooony
źródło
1
Uśpienie jest dostępne we frameworku .net - przyjrzyj się klasie wątku, np .: using System.Threading; .... Thread.Sleep (1000);
John Sibly,
2
Jeśli „ping 127.0.0.1” nie powiedzie się, musisz się martwić o coś poważniejszego niż „uśpienie” - to jest interfejs sprzężenia zwrotnego, wszystko, co RPC prawdopodobnie zwariuje.
Piskvor opuścił budynek
2

Najlepszym rozwiązaniem, które powinno działać na wszystkich wersjach systemu Windows po Windows 2000, byłoby:

timeout numbersofseconds /nobreak > nul
Tato
źródło
Nie działa na XP Pro ...'timeout' is not recognized as an internal or external command, operable program or batch file.
martineau
1

Plik pathping.exe może spać krócej niż sekundę.

@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
źródło
1

Jestem pod wrażeniem tego:

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

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

Technicznie rzecz biorąc, choicenakazujesz komendę zaakceptować tylko y. Domyślnie jest to y, aby zrobić to w ciągu 5 sekund, aby nie rysować monitu i zrzucać wszystko, co powie, do NUL (jak null terminal w Linuksie).

Chris Moschini
źródło
3
Powtórzę się tutaj: w ogóle tego nie polecam. W CHOICEwersjach, które znam, jeśli ktoś naciśnie klawisz podczas oczekiwania, co czasami robią niecierpliwi ludzie, wtedy wybór odczyta wejście, wyda sygnał dźwiękowy systemu dla złego wejścia i zatrzyma odliczanie, więc zawiesi się, chyba że naciśną Y. A jeśli zdarzy się, że naciśną Y, wtedy wybór kończy się właśnie na tym, zamiast czekać na 5. Ponadto ten wybór wykorzystuje naprawdę dziwną składnię Visty. Do tego służą zwykłe polecenia wyboru CHOICE /T:Y,5 > NUL. (W starszych wersjach nie ma flagi / D). Jeśli masz Vista, użyj TIMEOUTzamiast tego.
Kodowanie ze stylem,
1

Możesz również użyć pliku .vbs, aby wykonać określone limity czasu:

Poniższy kod tworzy plik .vbs. Umieść to w górnej części kodu partii:

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

Poniższy kod otwiera plik .vbs i określa, jak długo należy czekać:

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

W powyższym kodzie „1000” to wartość opóźnienia wysyłanego do pliku .vbs w milisekundach, na przykład 1000 ms = 1 s. Możesz zmienić tę część, aby była tak długa, jak chcesz.

Poniższy kod usuwa plik .vbs po zakończeniu pracy. Umieść to na końcu pliku wsadowego:

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

A oto cały kod, więc łatwo go skopiować:

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

Począwszy od systemu Windows Vista masz polecenia TIMEOUT i SLEEP , ale aby ich używać w systemie Windows XP lub Windows Server 2003, potrzebujesz zestawu narzędzi zasobów systemu Windows Server 2003 .

Tutaj masz dobry przegląd alternatywnych opcji uśpienia (metoda ping jest najpopularniejsza, ponieważ będzie działać na każdym komputerze z systemem Windows), ale nie wspomniano (przynajmniej) o jednej, która (ab) używa polecenia W32TM(Usługa czasu):

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

Gdzie powinieneś zamienić N na sekundy, które chcesz zatrzymać. Ponadto będzie działać na każdym systemie Windows bez wymagań wstępnych.

Można również użyć Typeperf:

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

Z mshta i javascript (może być używany do snu poniżej sekundy):

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

Powinno to być jeszcze bardziej precyzyjne (dla oczekiwania poniżej sekundy) - samokompilujący się plik wykonywalny oparty na .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
źródło
1

Istnieje wiele sposobów na to, aby zasnąć `` '' w cmd / partia:

Mój ulubiony:

TIMEOUT /NOBREAK 5 >NUL 2>NUL

Spowoduje to zatrzymanie konsoli na 5 sekund bez żadnego wyjścia.

Najbardziej używane:

ping localhost -n 5 >NUL 2>NUL

To spróbuje nawiązać połączenie do localhost5 razy. Ponieważ jest hostowany na twoim komputerze, zawsze dociera do hosta, więc co sekundę będzie próbował nowego co sekundę. Plik-nFlaga wskazuje, ile razy skrypt spróbuje nawiązać połączenie. W tym przypadku jest to 5, więc będzie to trwało 5 sekund.

Warianty ostatniego:

ping 1.1.1.1 -n 5 >nul

W tym skrypcie istnieją pewne różnice w porównaniu z ostatnim. To nie będzie próbowało zadzwonić localhost. Zamiast tego spróbuje połączyć się 1.1.1.1z bardzo szybką witryną. Akcja potrwa 5 sekund tylko wtedy, gdy masz aktywne połączenie internetowe. W przeciwnym razie ukończenie akcji potrwa około 15 . Nie polecam korzystania z tej metody.

ping 127.0.0.1 -n 5 >nul

To jest dokładnie to samo, co w przykładzie 2 (najczęściej używane). Możesz również użyć:

ping [::1] -n 5 >nul

Zamiast tego używa localhostwersji IPv6 .

Istnieje wiele metod wykonania tej czynności. Jednak preferuję metodę 1 dla systemu Windows Vista i nowszych wersji oraz najczęściej używaną metodę (metodę 2) dla wcześniejszych wersji systemu operacyjnego.

Lumito
źródło
0

Możesz nabrać ochoty, umieszczając wiadomość PAUSE na pasku tytułowym:

@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
źródło
0

Zostało to przetestowane w systemie Windows XP SP3 i Windows 7 i używa CScript. Umieściłem kilku bezpiecznych strażników, aby uniknąć podpowiedzi „” del. (/q byłoby niebezpieczne)

Poczekaj sekundę:

sleepOrDelayExecution 1000

Poczekaj 500 ms, a następnie uruchom program po:

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
Anonimowy tchórz
źródło
0

Ponieważ inni sugerują programy innych firm (Python, Perl, niestandardowa aplikacja itp.), Inną opcją jest GNU CoreUtils dla Windows dostępne pod adresem http://gnuwin32.sourceforge.net/packages/coreutils.htm .

2 opcje wdrożenia:

  1. Zainstaluj pełny pakiet (który będzie zawierał pełny zestaw CoreUtils, zależności, dokumentację itp.).
  2. Zainstaluj tylko plik binarny „sleep.exe” i niezbędne zależności (użyj depend.exe, aby pobrać zależności).

Jedną z korzyści z wdrożenia CoreUtils jest to, że dodatkowo otrzymasz wiele innych programów, które są pomocne w tworzeniu skryptów (wsad systemu Windows pozostawia wiele do życzenia).

codeniffer
źródło