Jak spać w pliku wsadowym?

132

Jak wstrzymać na chwilę wykonanie w pliku wsadowym systemu Windows między poleceniem a następnym?

Massimo
źródło
Czy to ma stać się kanonicznym? Jeśli tak, to może być odpowiedni tekst objaśniający.
John Gardeniers
2
„Tekst wyjaśniający” jak w?
Massimo,
2
Większość, jeśli nie wszystkie, pytania kanoniczne, które widziałem, zawierają tekst opisujący cel tego pytania.
John Gardeniers
Lub jakiś tekst wyjaśniający sytuację ... To głównie po to, aby pomóc w SEO, ale także pomaga wykreślić potencjalne Odpowiedzi.
Chris S
2
SEO działa dobrze. Pierwszy hit dla mnie w wyszukiwarce Google.
jbo5112

Odpowiedzi:

194

Prawidłowym sposobem na uśpienie w pliku wsadowym jest użycie timeoutpolecenia wprowadzonego w systemie Windows 2000.

Aby poczekać od 29 do 30 sekund :

timeout /t 30

Limit czasu zostanie przerwany, jeśli użytkownik naciśnie dowolny klawisz; jednak polecenie akceptuje również opcjonalny przełącznik /nobreak, który skutecznie ignoruje wszystko, co użytkownik może nacisnąć, z wyjątkiem jawnego CTRL-C:

timeout /t 30 /nobreak

Dodatkowo, jeśli nie chcesz, aby polecenie drukowało odliczanie na ekranie, możesz przekierować jego wynik do NUL:

timeout /t 30 /nobreak > NUL
Massimo
źródło
6
Polecenie limitu czasu nie działa w systemie Windows XP, nawet z zainstalowanym zestawem Resource Kit 2003, a polecenie uśpienia nie działa w systemie Windows 7, więc polecenie ping może nadal być przydatne, jeśli używasz pliku wsadowego zarówno w Win7, jak i WinXP.
12
limit czasu nie działa w skryptach nieinteraktywnych: „BŁĄD: Przekierowanie danych wejściowych nie jest obsługiwane, natychmiast wychodząc z procesu”. więc czasami preferowane jest użycie hacka z „ping”.
iMysak,
14

Ponieważ dotyczy to również tutaj, skopiuję moją odpowiedź z innej witryny .

Jeśli chcesz użyć polecenia ping, istnieje lepszy sposób. Będziesz chciał pingować adres, który nie istnieje, dzięki czemu możesz określić limit czasu z milisekundową precyzją. Na szczęście taki adres jest zdefiniowany w standardzie (RFC 3330) i tak jest 192.0.2.x. To nie jest wymyślone, to naprawdę adres, którego jedynym celem jest nieistnienie (może nie być jasne, ale dotyczy nawet sieci lokalnych):

192.0.2.0/24 - Ten blok jest przypisany jako „TEST-NET” do wykorzystania 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
3
Nie rób tego, nawet jeśli jest to trochę lepsze niż pingowanie prawdziwego adresu. Pingjest po prostu niewłaściwym narzędziem do pracy.
Massimo,
1
@Massimo Najprawdopodobniej nie jest to, co zamierzano zrobić :) Ale myślę, że nadal jest to dobre rozwiązanie - w niektórych scenariuszach (w szczególności w wyższej rozdzielczości) działa lepiej niż w przypadku przekroczenia limitu czasu. Ponadto stało się to dość dobrze znane, więc większość ludzi nie byłaby bardzo zaskoczona (tj. Zdezorientowana), gdy zobaczy to w pliku wsadowym.
mafu
2
@Massimo W porządku! Wydaje mi się, że mamy inne poglądy. Jeśli nie masz nic przeciwko, nadal zostawię tę odpowiedź, ponieważ wydaje się, że jest lepsza niż pingowanie localhost n razy, jak to najczęściej opisano.
mafu
7
Limit czasu jest właściwym rozwiązaniem dla systemów operacyjnych, na których działa. ping to jedyne rozwiązanie, które działa od 5.1-6.3. Przy 25% systemów wciąż w 5.1, limit czasu nie jest „właściwy”.
Wyrmwood,
3
limit czasu jest złym rozwiązaniem dla dowolnego systemu operacyjnego, ponieważ jest śmiertelnie uszkodzony nawet w systemie Windows 10. Do czego służy polecenie, które kończy się niepowodzeniem tylko z powodu przekierowania danych wejściowych?
Harry Johnston
8

Możesz także wstawić polecenie ping do hosta lokalnego. Zajmie to 4 sekundy (domyślnie). Przez niektórych uważany jest za kludge, ale mimo to działa całkiem dobrze.

Polecenie:
ping 127.0.0.1

akolita
źródło
6
Ehm ... głównym celem tego pytania / odpowiedzi było właśnie poprawienie dwóch innych pytań, które mają to jako zaakceptowaną odpowiedź, ale nie mogą być już poprawione, ponieważ ich OP nie jest już dostępny.
Massimo,
6
Chociaż zadziała, jest to odpowiednik wbijania śruby młotkiem. Niewłaściwe narzędzie może działać, ale nadal jest złe.
voretaq7
1
@MarkAllen Innymi słowy, Windows NT4, 95, 98, ME i starsze?
Chris McKeown,
5
@MarkAllen - technicznie musisz się martwić, czy pingsystem operacyjny jest dostępny. Jeśli martwisz się wystarczająco o '95 '98 lub ME, to powinieneś być równie zaniepokojeni 6.22, który nie posiada pingalbo
Mark Henderson
4
@ MarkHenderson Łatwiej (dla mnie) zapamiętać, czy dana wersja systemu operacyjnego obsługuje protokół TCP / IP, niż pamiętać, czy zawiera polecenie, którego wcześniej nie słyszałem. Wiesz?
Mark Allen
2

Oświadczenie : nie jest to „idealne” rozwiązanie, więc nie zawracaj mi głowy pobijaniem tego, co polecam ping...

Jeśli to możliwe, użyj timeoutna pewno. Ale jak zauważono w komentarzach, nie zawsze jest to opcja (np. W trybie nieinteraktywnym). Po tym zgadzam się, że ping„kludge” jest prawdopodobnie kolejną najlepszą opcją, ponieważ jest bardzo prosta. To powiedziawszy, oferuję inną opcję ... osadzić skrypt VB .

Podstawa tego rozwiązania ma wiele innych zastosowań. Często VBS potrafi robić rzeczy, których partia nie może, lub przynajmniej robi to z drastycznie większą łatwością. Korzystając z przedstawionej tutaj techniki, możesz je mieszać (nie „płynnie”, ale „funkcjonalnie” ...).

Oto jeden linijka, aby utworzyć skrypt tymczasowy, wykonać go, a następnie usunąć. Skrypt śpi dla ciebie (w tym przykładzie przez 3 sekundy).

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

Oto w zasadzie ta sama rzecz, napisana nieco inaczej:

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

I wreszcie, jak ping, CScriptsama posiada opcję limitu czasu! Tak więc, jeśli wejdziesz w nieskończoną pętlę w skrypcie, możesz pozwolić tłumaczowi na wymuszanie czasu trwania. Uwaga: jest to operacja „zajęta”, która zjada procesor, dlatego nie polecam jej, gdy można skorzystać z tej WScript.Sleepprocedury, ale przedstawiam ją jako koncepcyjną opcję ze względu na kompletność:

set sleepSec=3 & set sleepVbs=%temp%\sleep.vbs & echo While True > %sleepVbs% & echo Wend >> %sleepVbs% & cscript %sleepVbs% //B //T:%sleepSec% & del %sleepVbs%
BuvinJ
źródło
Wiesz ... możesz to zrobić w PowerShell, nie oczekuję, aby napisać plik.
Harry Johnston,
Tak, to prawdopodobnie kolejne dobre rozwiązanie, choć uważam, że jest bardziej kompatybilne wstecz ze starszymi wersjami systemu Windows.
BuvinJ