Ngủ trong một tập tin hàng loạt


151

Khi viết một tệp bó để tự động hóa một cái gì đó trên hộp Windows, tôi cần tạm dừng quá trình thực thi của nó trong vài giây (thường là trong vòng kiểm tra / chờ, chờ quá trình bắt đầu). Vào thời điểm đó, giải pháp tốt nhất tôi có thể tìm thấy sử dụng ping (Tôi không phải bạn) để đạt được hiệu quả mong muốn. Tôi đã tìm thấy một bài viết tốt hơn về nó ở đây , trong đó mô tả một "Wait.bat" có thể gọi được, được triển khai như sau:

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

Sau đó, bạn có thể bao gồm các cuộc gọi đến Wait.bat trong tệp bó của riêng bạn, chuyển qua số giây để ngủ.

Rõ ràng Bộ tài nguyên Windows 2003 cung cấp một lệnh ngủ giống như Unix (cuối cùng!). Trong khi đó, đối với những người trong chúng ta vẫn đang sử dụng Windows XP, Windows 2000 hoặc (đáng buồn thay) Windows NT , có cách nào tốt hơn không?

Tôi đã sửa đổi sleep.pytập lệnh trong câu trả lời được chấp nhận , để nó mặc định thành một giây nếu không có đối số nào được truyền trên dòng lệnh:

import time, sys

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

Trang tải xuống Microsoft của Bộ tài nguyên Windows 2003 cho biết rằng nó cũng hoạt động cho XP. Tôi e rằng không có lựa chọn nào khác ngoài việc sử dụng tiện ích 'bên ngoài' để chờ đợi: không có gì giống như điều này được tích hợp trong bộ xử lý lệnh XP.
GerG

Bộ tài nguyên máy chủ 2003 hoạt động với Windows XP (và có thể với w2k)
Martin Beckett

Tôi đã đối mặt với cùng một vấn đề trong quá khứ và đã sử dụng ping cho chính mình (với một nhận xét ở trên ghi lại rõ ràng rằng tôi nhận ra điều này là ngu ngốc :)).
Jack Leow


2
Bạn có một vài tùy chọn - giả lập một giấc ngủ bằng pinglệnh hoặc tải xuống bộ tài nguyên windows bao gồm một sleeplệnh. Thêm chi tiết tại đây: Tập tin hàng loạt Lệnh SLEEP
Rudu

Câu trả lời:


14

CẬP NHẬT

Các timeoutlệnh, sẵn từ Windows Vista trở đi nên được lệnh sử dụng, như được mô tả trong một câu trả lời cho câu hỏi này. Điều gì sau đây là một câu trả lời .

Câu trả lời cũ

Nếu bạn có cài đặt Python, hoặc không nhớ cài đặt nó (nó có công dụng khác nữa :), chỉ cần tạo những điều sau sleep.py kịch bản và thêm nó ở đâu đó trong PATH của bạn:

import time, sys

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

Nó sẽ cho phép tạm dừng giây phụ (ví dụ: 1,5 giây, 0,1, v.v.), nếu bạn có nhu cầu như vậy. Nếu bạn muốn gọi nó là sleepthay vì sleep.py, thì bạn có thể thêm .PYphần mở rộng vào biến môi trường PATHEXT của mình. Trên Windows XP, bạn có thể chỉnh sửa nó trong:

Máy tính của tôi → Thuộc tính (menu) → Nâng cao (tab) → Biến môi trường (nút) → Biến hệ thống (khung)


32
Tại sao chúng ta nên viết một tập lệnh bằng python khi yêu cầu giải pháp tập lệnh theo tập lệnh? Làm cách nào để mở rộng đường dẫn có thể giải quyết vấn đề mà người dùng Windows chưa cài đặt trình thông dịch python? Cảm ơn.
Val

6
Vì lợi ích của tính di động, tôi nghĩ giải pháp này nên tránh vì có những lựa chọn thay thế hoàn toàn tốt.
Gras Double

1
Cách tiếp cận này có thể đã cung cấp một cách giải quyết trong quá khứ, nhưng giải pháp tự nhiên được mô tả bởi @Blorgbeard chắc chắn là cách tốt nhất.
Mike

227

Các timeoutlệnh có sẵn từ Windows Vista trở đi:

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

Lưu ý: Nó không hoạt động với chuyển hướng đầu vào - ví dụ tầm thường:

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

8
không hoạt động trong các sử dụng không có bàn điều khiển: "LRI: Chuyển hướng đầu vào không được hỗ trợ, thoát khỏi quy trình ngay lập tức."
đơn giản

Ý tôi là các trường hợp bạn hoàn toàn không có bàn điều khiển, chẳng hạn như khi tệp bó được chạy trong nền thông qua một ngã ba từ một quá trình khác, cygwin crontab hoặc lệnh ssh từ xa, v.v.
Trình đơn giản hóa

1
Ồ vâng tôi biết. Ví dụ tôi đưa ra chỉ là để chứng minh lỗi :)
Blorgbeard ra

3
Các liên kết đến tài liệu cho timeout, bổ sung bởi @Cristian Ciupitu, là một phần sai - Windows XP không có lệnh này.
martineau

1
@HelloWorld nghe có vẻ như là một vấn đề với% PATH% của bạn
Blorgbeard đã hết

21

Sử dụng pingphương pháp như đã phác thảo là cách tôi thực hiện khi tôi không thể (hoặc không muốn) thêm nhiều tệp thực thi hoặc cài đặt bất kỳ phần mềm nào khác.

Bạn nên ping cái gì đó không có ở đó, và sử dụng -wlá cờ để nó thất bại sau khi khoảng thời gian đó, không ping cái gì đó có (như localhost) -nlần. Điều này cho phép bạn xử lý thời gian ít hơn một giây và tôi nghĩ nó chính xác hơn một chút.

ví dụ

(kiểm tra 1.1.1.1 không được thực hiện)

ECHO Waiting 15 seconds

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

Trả lại ngay lập tức vớiPING: transmit failed. General failure.
huysentbeanw

IP 1.1.1.1được CloudFlare lấy, do đó, điều này sẽ không đợi 15 giây mà khoảng một vài ms.
dhcgn

16

SLEEP.exeđược bao gồm trong hầu hết các Bộ tài nguyên, ví dụ Bộ tài nguyên Windows Server 2003 cũng có thể được cài đặt trên Windows XP.

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

15

Tôi không đồng ý với câu trả lời tôi tìm thấy ở đây.

Tôi sử dụng phương pháp sau hoàn toàn dựa trên các khả năng của Windows XP để thực hiện độ trễ trong tệp bó:

TRÌ HOÃN:

@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

Bạn cũng có thể chèn ngày trong phép tính để phương thức cũng hoạt động khi khoảng thời gian trễ vượt qua nửa đêm.


15
Điều này là chính xác, nhưng nó là một cách chuyên sâu về CPU. Thông thường, bạn muốn triển khai theo hướng gián đoạn để quá trình không tiêu tốn chu kỳ CPU trong khi chờ. Đây không phải là một vấn đề cho sự chờ đợi không thường xuyên, như có lẽ là trường hợp đối với hầu hết các tình huống hàng loạt. Nhưng một quá trình chạy liên tục với thời gian chờ đợi lâu có thể có tác động tiêu cực đến hiệu suất hệ thống.
dbenham

4
Vì nó sử dụng đồng hồ hệ thống, độ chính xác là một giây. Nếu chỉ định 2 giây, độ trễ có thể là bất cứ thứ gì trong khoảng từ 2 giây đến 3 giây (thực tế là 2,99999 ... giây).
Peter Mortensen

Điều gì sẽ xảy ra nếu thời gian là 7:59:59 và bạn muốn đợi 7 giây? Có vẻ như nó không tính đến điều đó.
tro999

Điều này tiêu tốn nhiều thời gian CPU hơn so với thời gian hệ thống. Ngoài ra, bạn đang thực hiện các phép toán số học với số bát phân, vì phút và giây nhỏ hơn 10 được hiển thị với số 0 đứng đầu trong TIMElệnh.
Andreas

2
@mrt: Vấn đề là bạn %TIME%sử dụng dấu phẩy để phân tách phần trăm giây, thay vì một điểm! Chỉ cần thêm dấu phẩy vào DELIMS=:.,"...
Aacini

13

Tôi đã đối mặt với một vấn đề tương tự, nhưng tôi chỉ cần gõ một ứng dụng bảng điều khiển C ++ rất ngắn để làm điều tương tự. Chỉ cần chạy MyS ngủ.exe 1000 - có lẽ dễ dàng hơn so với tải xuống / cài đặt toàn bộ bộ tài nguyên.

#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;
}

10

Tại Server Fault, một câu hỏi tương tự đã được đặt ra và giải pháp là:

choice /d y /t 5 > nul

7
FYI: Sự lựa chọn không được bao gồm trong Windows XP. Nó đã có trong Windows 9x, được gỡ bỏ khỏi XP và được thêm lại cho Vista trở đi.
Devin Burke

7
Tôi không đề nghị điều này cả. Ít nhất trong tất cả các CHOICEphiên bản mà tôi biết, nếu ai đó nhấn nút trong khi chờ đợi, đôi khi những người thiếu kiên nhẫn làm điều đó, thì sự lựa chọn sẽ đăng ký đầu vào, đưa ra một tiếng bíp hệ thống cho đầu vào xấu và tạm dừng đồng hồ đếm ngược, có nghĩa là nó sẽ bị treo ở đó trừ khi họ đẩy N hoặc Y. Và nếu họ tình cờ đẩy một trong hai người đó, thì lựa chọn kết thúc ngay tại đó thay vì chờ 5. Ngoài ra, lựa chọn này đang sử dụng cú pháp Vista thực sự kỳ lạ. Thay vào đó, tất cả các lệnh lựa chọn thông thường sẽ sử dụng CHOICE /T:Y,5 > NULcho điều đó. Không có /Dcờ trong các phiên bản cũ.
Mã hóa với phong cách

1
Trên hết, ít nhất các lệnh CHOICE mà tôi biết có các nút có / không mặc định khác nhau dựa trên ngôn ngữ mà nó xuất hiện, vì vậy nếu bạn tình cờ dựa vào lựa chọn [Y, N] mặc định thay vì chỉ định rõ ràng bằng /C:YNhoặc chỉ /C:Y, điều này sẽ không hoạt động khi ai đó tình cờ có một lệnh lựa chọn của Thụy Điển có thể sẽ thực hiện [J, N] theo mặc định. Vì vậy, điều này bị sa lầy trong tất cả các loại rắc rối.
Mã hóa với phong cách

1
@Coding Đã thử nghiệm điều này trong Win7 và nếu người dùng nhấn nút, nó sẽ phát ra tiếng bíp, tuy nhiên nó vẫn sẽ hết thời gian chờ sau 5 giây nữa sau khi người dùng nhấn nút. Vì vậy, nếu người dùng tiếp tục nhấn phím, nó sẽ không bao giờ hết thời gian. Ngoài ra, trong trường hợp của tôi, khi tôi sử dụng cái này, tôi tin rằng ẩn bảng điều khiển, để người dùng không thể nhấn nút. Trên hệ thống này, không có quyền truy cập vào Python, không có quyền truy cập để thả exe của riêng tôi trên hệ thống (như được đề xuất trong một số câu trả lời khác), tôi khá hạn chế trong những gì tôi có thể làm. Vì vậy, những gì bạn sẽ đề nghị?
mlsteeves

@mlsteeves Mỗi Windows, DOS, v.v. khác nhau có một lệnh lựa chọn khác nhau và như đã lưu ý, nó thường không có sẵn trong Xp. Nhiều lệnh lựa chọn có hành vi khác nhau tinh tế và một số thậm chí có cú pháp khác nhau. Tôi, tôi thường sử dụng lệnh ping khi tôi cần ngủ. Thật xấu xí, nhưng đáng tin cậy.
mã với Phong cách

9

Bạn có thể sử dụng lớp WSH của Windows cscript và tệp JavaScript Wait.js này :

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

1
Mặc dù vậy, Windows Scripting Host có thể bị vô hiệu hóa thông qua các chính sách nhóm.
Joey

8

Tùy thuộc vào nhu cầu tương thích của bạn, sử dụng ping:

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

ví dụ chờ 5 giây, sử dụng

ping -n 6 localhost >nul 2>&1

hoặc trên Windows 7 trở lên sử dụng timeout:

timeout 6 >nul

2
-wtính bằng mili giây, -nchỉ là số lần ping và thời gian mặc định giữa các lần ping là một giây.
Joey

8

Bạn có thể sử dụng ping:

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

Nó sẽ đợi 10 giây.

Lý do bạn phải sử dụng 11 là vì ping đầu tiên tắt ngay lập tức, không phải sau một giây. Số phải luôn luôn nhiều hơn số giây bạn muốn chờ.

Hãy nhớ rằng mục đích của việc -wkhông phải đợi một giây. Đó là để đảm bảo rằng bạn chờ đợi không có nhiều hơn một giây trong trường hợp có vấn đề về mạng. pingtự nó sẽ gửi một gói ICMP mỗi giây. Có lẽ không cần thiết cho localhost, nhưng thói quen cũ chết cứng.


không nên sử dụng điều này để xử lý thời gian thực quan trọng. bởi vì lệnh PING đang được sử dụng, có thể tệp bó WAIT này có thể chạy trong vài mili giây
Wael Dalloul

12
@Wael, nếu bạn đang nói về việc chờ đợi trên ranh giới một giây, một vài mili giây sẽ không liên quan. Và nếu bạn đang sử dụng cmd.exe cho công cụ thời gian thực, bạn xứng đáng với mọi thứ bạn nhận được :-)
paxdiablo

-w là một giá trị thời gian chờ. Đó là số mili giây để chờ trả lời ... không phải là thời gian chờ giữa các lần ping.
quux

@quux, không có nơi nào tôi nói -wlà hết thời gian (mặc dù tôi thừa nhận một số có thể suy luận rằng do tôi không rõ ràng), nó thực sự được sử dụng để hạn chế thời gian chu kỳ trong đó có các sự cố mạng sẽ khiến mỗi chu kỳ mất nhiều hơn so với phân bổ thứ hai. Tôi đã thêm một đoạn vào cuối để làm rõ điều này.
paxdiablo

vấn đề là nếu ping trở lại nhanh hơn , bạn có thể không đợi một giây đầy đủ giữa các ping. vì vậy vòng chờ của bạn sẽ kết thúc nhanh hơn bạn nghĩ
quux

7

Có một cách tốt hơn để ngủ bằng cách sử dụng ping. Bạn sẽ muốn ping một địa chỉ không tồn tại, vì vậy bạn có thể chỉ định thời gian chờ với độ chính xác đến mili giây. May mắn thay, một địa chỉ như vậy được xác định trong một tiêu chuẩn (RFC 3330), và nó là 192.0.2.x. Đây không phải là trang điểm, nó thực sự là một địa chỉ với mục đích duy nhất là không tồn tại (nó có thể không rõ ràng, nhưng nó được áp dụng ngay cả trong các mạng cục bộ):

192.0.2.0/24 - Khối này được gán là "TEST-NET" để sử dụng trong tài liệu và mã ví dụ. Nó thường được sử dụng cùng với tên miền example.com hoặc example.net trong tài liệu về nhà cung cấp và giao thức. Địa chỉ trong khối này sẽ không xuất hiện trên Internet công cộng.

Để ngủ trong 123 mili giây, sử dụng ping 192.0.2.1 -n 1 -w 123 >nul


Vâng, đây là dễ dàng hơn để viết và hiểu được vì phải thêm một đến -ntham số.
Peter Mortensen

Tuy nhiên, tôi đã đo nó (sử dụng 100 ping). Nếu tôi sử dụng -n 3 -w 124, thời gian thực tế chính xác là (3 + 1) * (124 + 1) = 4 * 125 = 500 ms. Thời gian ổn định đáng ngạc nhiên, chính xác đến độ phân giải 10 ms trong quá trình đọc (theo dấu nhắc của CMD theo thời gian) - và độ phân giải cơ bản chắc chắn tốt hơn 10 ms (không bị ảnh hưởng bởi độ phân giải 16 ms thông thường).
Peter Mortensen

@mafu Không nên sử dụng 192.0.2.0/24 không có nghĩa là không thể sử dụng và do đó không thực sự đảm bảo rằng không có phản hồi về (các) yêu cầu tiếng vang. Ví dụ: cấu hình cho mọi PC Windows, địa chỉ IPv4 tĩnh 192.0.2.1 và mặt nạ mạng con 255.255.255.0 và kết nối bộ điều hợp mạng với bất kỳ thiết bị nào khác. Một chuyển đổi đơn giản là đủ mà không có gì khác được kết nối. Sau đó chạy ping 192.0.2.1trên PC Windows này và có thể thấy rằng ngăn xếp TCP / IP của Windows trả lời các yêu cầu echo. Có bao nhiêu người biết rằng 192.0.2.0/24 không nên được sử dụng cho một địa chỉ IPv4 tĩnh?
Mofi

1
Theo các cuộc thảo luận trong các ý kiến ở đây , có vẻ như 192.0.2.1 không phải là hoàn hảo và một số người cho rằng 127.255.255.255 là một lựa chọn tốt hơn. Suy nghĩ?
JLRishe

Các ý kiến ​​được đề cập trong bài đăng ở trên hiện đã bị xóa (có thể là NLN), nhưng tôi đồng ý với thay đổi 127.255.255.255do đây là địa chỉ loopback quảng bá trong Windows đã được gán theo mặc định (Bạn có thể xác nhận điều này bằng cách chạy route printtrong cmd và xem qua bảng định tuyến IPv4 mà nó in).
Hoppeduppeanut

6

Nếu bạn đã có PowerShell trên hệ thống của mình, bạn có thể thực hiện lệnh này:

powershell -command "Start-Sleep -s 1"

Chỉnh sửa: từ câu trả lời của tôi về một chủ đề tương tự , mọi người nêu ra một vấn đề trong đó lượng thời gian quyền hạn cần có để bắt đầu là đáng kể so với thời gian bạn đang cố gắng chờ đợi. Nếu độ chính xác của thời gian chờ là quan trọng (nghĩa là độ trễ thêm một hoặc hai giây không được chấp nhận), bạn có thể sử dụng phương pháp này:

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

Điều này sẽ mất thời gian khi lệnh windows được ban hành và tập lệnh powershell ngủ đến 5 giây sau thời gian đó. Vì vậy, miễn là quyền hạn mất ít thời gian để bắt đầu hơn thời gian ngủ của bạn, phương pháp này sẽ hoạt động (khoảng 600ms trên máy của tôi).


6
timeout /t <seconds> <options>

Ví dụ: để làm cho tập lệnh thực hiện chờ 2 giây không bị gián đoạn:

timeout /t 2 /nobreak >NUL

Có nghĩa là kịch bản sẽ đợi 2 giây trước khi tiếp tục.

Theo mặc định, tổ hợp phím sẽ làm gián đoạn thời gian chờ, vì vậy hãy sử dụng công /nobreaktắc nếu bạn không muốn người dùng có thể ngắt (hủy) chờ. Hơn nữa, thời gian chờ sẽ cung cấp thông báo mỗi giây để thông báo cho người dùng thời gian chờ đợi; điều này có thể được loại bỏ bằng cách dẫn lệnh đến NUL.

chỉnh sửa: Như @martineau chỉ ra trong các bình luận , timeoutlệnh chỉ khả dụng trên Windows 7 trở lên. Hơn nữa, pinglệnh sử dụng ít thời gian xử lý hơn timeout. timeoutMặc dù vậy, tôi vẫn tin tưởng vào việc sử dụng khi có thể, vì nó dễ đọc hơn ping'hack'. Đọc thêm ở đây .


2
Rõ ràng lệnh này chỉ có sẵn trong Windows 7/2008 và Bộ tài nguyên XP (và có thể là 8 / 8.1). Nguồn này cũng tuyên bố pingcách tiếp cận sử dụng ít thời gian xử lý hơn.
martineau

5

Chỉ cần đặt nó trong tập tin hàng loạt của bạn, nơi bạn muốn chờ đợi.

@ping 127.0.0.1 -n 11 -w 1000 > null

Điều này khác với câu trả lời của paxdiablo như thế nào?
Peter Mortensen

2
Nó không khác nhau, nhưng câu trả lời ở đây là từ nhiều câu hỏi được hợp nhất, vì vậy không phải tất cả các câu trả lời đều tồn tại khi tôi trả lời.
Brent Stewart

4

Trong Notepad, viết:

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

Bây giờ hãy lưu dưới dạng Wait.bat trong thư mục C: \ WINDOWS \ System32, sau đó bất cứ khi nào bạn muốn chờ, hãy sử dụng:

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

Nó tự lặp đi lặp lại, đợi một giây giữa mỗi ping và sau đó nó quay lại chương trình gọi, tôi không thấy vòng lặp vô hạn, nhưng tôi đã tự mình kiểm tra nó.
SuperKael

Sai lầm của tôi, không có vòng lặp vô hạn. Tuy nhiên, như đã đề cập trong một trong những câu trả lời khác , tốt hơn là pingkhông chỉ một lần và sử dụng -w Timeouttùy chọn cho thời gian trễ tính bằng mili giây thay vì -n Counttoàn bộ tùy chọn số lần thử lại.
martineau

-w Timeoutcó thể tốt hơn, nhưng tôi chắc chắn rằng nó sẽ quay một lần nữa so với thời gian đã nhập.
SuperKael

4

Bộ tài nguyên luôn luôn bao gồm điều này. Ít nhất là kể từ Windows 2000.

Ngoài ra, gói Cygwin có sleep- nhập vào PATH của bạn và bao gồm cygwin.dll(hoặc bất cứ thứ gì nó được gọi) và cách để đi!


2
Lưu ý rằng cygwin1.dll không cùng tồn tại một cách hòa bình với các phiên bản khác nhau của chính nó. Tốt hơn là bạn nên có một và chỉ một cygwin1.dll trên máy của mình, nếu không bạn sẽ gặp phải những thất bại kỳ lạ.
JesperE

Bộ tài nguyên nào? Dường như có nhiều hơn một. Bạn có thể cập nhật câu trả lời của bạn?
Peter Mortensen

3

Tôi thích phản ứng của Aacini . Tôi đã thêm vào nó để xử lý ngày và cũng cho phép nó xử lý centiseconds ( %TIME%đầu ra 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

3

Tôi đã được sử dụng chương trình ngủ C # này. Có thể thuận tiện hơn cho bạn nếu C # là ngôn ngữ ưa thích của bạn:

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

Thậm chí nhẹ hơn giải pháp Python là một lớp lót Perl.

Để ngủ trong bảy giây, hãy đặt cái này vào tập lệnh BAT:

perl -e "sleep 7"

Giải pháp này chỉ cung cấp độ phân giải một giây.

Nếu bạn cần độ phân giải cao hơn thì hãy sử dụng mô-đun Time :: HiRes từ CPAN. Nó cung cấp chế độ usleep()ngủ nào tính bằng micrô giây và nanosleep()ngủ trong nano giây (cả hai hàm chỉ lấy đối số nguyên). Xem câu hỏi Stack Overflow Làm thế nào để tôi ngủ trong một phần nghìn giây trong Perl? để biết thêm chi tiết.

Tôi đã sử dụng ActivePerl trong nhiều năm. Nó là rất dễ dàng để cài đặt.


2

Hoặc dòng lệnh Python, ví dụ, trong 6 giây rưỡi:

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

Mặc dù ngắn hơn, đây là một bản sao của câu trả lời được chấp nhận.
Peter Mortensen

@Peter Mortensen: Nó cũng cho phép bạn dễ dàng đặt mọi thứ vào một dòng duy nhất của một tệp bó.
martineau

2

Việc sử dụng ping là tốt, miễn là bạn chỉ muốn "chờ một chút". Điều này do bạn phụ thuộc vào các chức năng khác bên dưới, như mạng của bạn hoạt động và thực tế là không có gì trả lời trên 127.0.0.1. ;-) Có thể không có khả năng nó thất bại, nhưng không phải là không thể ...

Nếu bạn muốn chắc chắn rằng bạn đang đợi chính xác thời gian đã chỉ định, bạn nên sử dụng sleep chức năng (điều này cũng có lợi thế là nó không sử dụng nguồn CPU hoặc chờ mạng sẵn sàng).

Để tìm một thực thi đã được thực hiện cho giấc ngủ là cách thuận tiện nhất. Chỉ cần thả nó vào thư mục Windows của bạn hoặc bất kỳ phần nào khác của đường dẫn tiêu chuẩn của bạn và nó luôn có sẵn.

Mặt khác, nếu bạn có một môi trường biên dịch, bạn có thể dễ dàng tạo một cái cho riêng mình. Các Sleepchức năng có sẵn trong kernel32.dll, vì vậy bạn chỉ cần sử dụng chức năng đó. :-) Đối với VB / VBA, hãy khai báo phần sau trong phần đầu của nguồn để khai báo hàm ngủ:

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

Đối với C #:

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

Bạn sẽ tìm thấy ở đây nhiều hơn về chức năng này (có sẵn từ Windows 2000) trong chức năng Ngủ (MSDN).

Trong tiêu chuẩn C, sleep()được bao gồm trong thư viện tiêu chuẩn và trong Visual Studio C của Microsoft, chức năng được đặt tên Sleep(), nếu bộ nhớ phục vụ cho tôi. ;-) Hai cái đó lấy đối số tính bằng giây, không tính bằng mili giây như hai khai báo trước.


1
Ngủ có sẵn trong khung .net - hãy xem lớp luồng, ví dụ: bằng cách sử dụng System.Threading; .... Chủ đề. Ngủ (1000);
John Sizable

2
Nếu "ping 127.0.0.1" không thành công, bạn có vấn đề nghiêm trọng hơn là "ngủ" - đây là giao diện loopback, mọi thứ RPC có thể sẽ phát điên.
Piskvor rời khỏi tòa nhà vào

2

Giải pháp tốt nhất nên hoạt động trên tất cả các phiên bản Windows sau Windows 2000 sẽ là:

timeout numbersofseconds /nobreak > nul

Không hoạt động trên XP Pro ...'timeout' is not recognized as an internal or external command, operable program or batch file.
martineau

1

Pathping.exe có thể ngủ ít hơn giây.

@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

Tôi ấn tượng với điều này:

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

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

Về mặt kỹ thuật, bạn đang nói choicelệnh chỉ chấp nhận y. Nó mặc định là y, để làm như vậy trong 5 giây, không rút ra lời nhắc nào và bỏ đi bất cứ điều gì nó nói với NUL (như thiết bị đầu cuối null trên Linux).


3
Tôi sẽ lặp lại ở đây: Tôi không đề nghị điều này cả. Trong các CHOICEphiên bản mà tôi biết, nếu ai đó nhấn phím trong khi chờ đợi, đôi khi những người thiếu kiên nhẫn làm điều đó, thì sự lựa chọn sẽ đọc một đầu vào, đưa ra một tiếng bíp hệ thống cho đầu vào xấu và tạm dừng đếm ngược, vì vậy nó sẽ bị treo trừ khi họ đẩy Y. Và nếu họ tình cờ đẩy Y, thì lựa chọn kết thúc ngay tại đó thay vì chờ 5. Ngoài ra, lựa chọn này đang sử dụng cú pháp Vista thực sự kỳ lạ. Các lệnh lựa chọn bình thường thay vì sử dụng CHOICE /T:Y,5 > NULcho điều đó. (Không có cờ / D trong các phiên bản cũ.) Và nếu bạn có Vista, hãy sử dụng TIMEOUTthay thế.
Mã hóa với phong cách

1

Bạn cũng có thể sử dụng tệp .vbs để thực hiện thời gian chờ cụ thể:

Mã dưới đây tạo tệp .vbs. Đặt cái này gần đầu mã rbatch của bạn:

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

Đoạn mã dưới đây sẽ mở .vbs và chỉ định thời gian chờ đợi:

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

Trong đoạn mã trên, "1000" là giá trị độ trễ thời gian được gửi đến tệp .vbs tính bằng mili giây, ví dụ: 1000 ms = 1 s. Bạn có thể thay đổi phần này để được bao lâu bạn muốn.

Đoạn mã dưới đây sẽ xóa tệp .vbs sau khi bạn hoàn thành nó. Đặt phần này vào cuối tệp bó của bạn:

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

Và đây là mã tất cả cùng nhau để dễ dàng sao chép:

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

1

Từ Windows Vista trở đi, bạn có các lệnh TIMEOUTSLEEP , nhưng để sử dụng chúng trên Windows XP hoặc Windows Server 2003, bạn sẽ cần bộ công cụ tài nguyên Windows Server 2003 .

Ở đây bạn có một cái nhìn tổng quan về các lựa chọn thay thế giấc ngủ (phương pháp ping là phổ biến nhất vì nó sẽ hoạt động trên mọi máy Windows), nhưng có (ít nhất) một cái không được đề cập (ab) sử dụng lệnh W32TM(Dịch vụ thời gian):

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

Nơi bạn nên thay thế N bằng giây bạn muốn tạm dừng. Ngoài ra, nó sẽ hoạt động trên mọi hệ thống Windows mà không cần điều kiện tiên quyết.

Máy đánh chữ cũng có thể được sử dụng:

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

Với mshta và javascript (có thể được sử dụng cho giấc ngủ dưới một giây):

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

Điều này thậm chí còn chính xác hơn (để chờ dưới một giây) - tự biên dịch thực thi dựa trên .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);
}

1

Có rất nhiều cách để thực hiện một ' giấc ngủ ' tính bằng cmd / đợt:

Điêu ưa thich của tôi:

TIMEOUT /NOBREAK 5 >NUL 2>NUL

Điều này sẽ dừng giao diện điều khiển trong 5 giây, mà không có bất kỳ đầu ra.

Được dùng nhiều nhất:

ping localhost -n 5 >NUL 2>NUL

Điều này sẽ cố gắng thực hiện kết nối đến localhost5 lần. Vì nó được lưu trữ trên máy tính của bạn, nó sẽ luôn đến máy chủ, vì vậy mỗi giây nó sẽ thử cái mới mỗi giây. Các -ncờ biết có bao nhiêu lần so với kịch bản sẽ cố gắng kết nối. Trong trường hợp này là 5, vì vậy nó sẽ kéo dài 5 giây.

Các biến thể của cái cuối cùng:

ping 1.1.1.1 -n 5 >nul

Trong kịch bản này có một số khác biệt so sánh nó với cái cuối cùng. Điều này sẽ không cố gắng để gọi localhost. Thay vào đó, nó sẽ cố gắng kết nối với 1.1.1.1, một trang web rất nhanh. Hành động sẽ chỉ kéo dài 5 giây nếu bạn có kết nối internet đang hoạt động. Khác nó sẽ kéo dài khoảng 15 để hoàn thành hành động . Tôi không khuyên bạn nên sử dụng phương pháp này.

ping 127.0.0.1 -n 5 >nul

Điều này hoàn toàn giống với ví dụ 2 (được sử dụng nhiều nhất). Ngoài ra, bạn cũng có thể sử dụng:

ping [::1] -n 5 >nul

Thay vào đó, sử dụng localhostphiên bản IPv6 .

Có rất nhiều phương pháp để thực hiện hành động này. Tuy nhiên, tôi thích phương pháp 1 cho Windows Vista và các phiên bản mới hơn và phương thức được sử dụng nhiều nhất (phương pháp 2) cho các phiên bản trước của HĐH.


0

Bạn có thể nhận được ưa thích bằng cách đặt thông báo PAUSE vào thanh tiêu đề:

@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

Điều này đã được thử nghiệm trên Windows XP SP3 và Windows 7 và sử dụng CScript. Tôi đặt một số bảo vệ an toàn để tránh del "" nhắc nhở. ( /qsẽ nguy hiểm)

Chờ đợi một giây:

ngủOrDelayExecut 1000

Đợi 500 ms và sau đó chạy công cụ sau:

sleepOrDelayExecution 500 dir \ /s

ngủOrDelayExecut.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

Vì các chương trình khác đang đề xuất các chương trình của bên thứ 3 (Python, Perl, ứng dụng tùy chỉnh, v.v.), một tùy chọn khác là GNU CoreUtils cho Windows có sẵn tại http://gnuwin32.sourceforge.net/packages/coreutils.htmlm .

2 tùy chọn để triển khai:

  1. Cài đặt gói đầy đủ (sẽ bao gồm bộ CoreUtils đầy đủ, phụ thuộc, tài liệu, v.v.).
  2. Chỉ cài đặt phụ thuộc nhị phân 'ngủ.exe' và phụ thuộc cần thiết (sử dụng phụ thuộc.exe để nhận phụ thuộc).

Một lợi ích của việc triển khai CoreUtils là bạn cũng sẽ nhận được một loạt các chương trình khác hữu ích cho việc viết kịch bản (lô Windows để lại rất nhiều mong muốn).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.