Ngủ cho đến lần xuất hiện tiếp theo của thời gian cụ thể


11

Tôi cần một loạt các lệnh hoặc một lệnh duy nhất ngủ cho đến khi xảy ra lần tiếp theo của một thời điểm cụ thể như "4:00".

Làm thế nào tôi có thể làm điều đó?

Các atlệnh hoặc một cronjob không phải là một lựa chọn vì tôi không phải rời khỏi kịch bản Tôi hiện tại là.

Trường hợp cụ thể mà tôi đang nói đến là một kịch bản chạy trên màn hình. Điều rất quan trọng là tôi không dừng việc thực thi tập lệnh bằng chính tập lệnh bởi vì có một số biến quan trọng cần thiết tại một số điểm của tập lệnh. Kịch bản không phải luôn luôn được thực hiện trong một vấn đề thông thường. Nó chỉ cần được thực hiện tại một thời điểm cụ thể.

Sẽ rất có lợi nếu tập lệnh sẽ phải tạo bất kỳ tệp hoặc bất kỳ tác vụ nào khác như cronjobs hoặc các màn hình khác. Đây chỉ đơn giản là một câu hỏi về thiết kế.

Tôi chỉ có một ý tưởng tuyệt vời:

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

Bạn có ý tưởng nào tốt hơn không?

Thông tin thêm sẽ được thêm vào nếu được yêu cầu!


Xin vui lòng bạn có thể làm rõ một chút câu hỏi của bạn? Ý bạn là gì khi bạn nói: "Tôi không được rời khỏi kịch bản mà tôi hiện đang ở"
sebelk

Làm thế nào về việc bạn kiểm tra tập lệnh của mình cho sự tồn tại của tệp "đánh thức" và ngủ trong một khoảng thời gian trước khi kiểm tra lại? Sau đó, bạn có thể sử dụng cron để tạo tệp, nâng cao độ tin cậy của cron, nhưng bạn cũng có thể có tập lệnh dài hạn của mình. Chỉ cần có tập lệnh loại bỏ tập tin "đánh thức" khi nó ngừng ngủ.
kurtm

Lưu ý rằng trên một máy Mac, bạn nên thay thế date -dvới date -jvà thay thế 4:00với 0400.
pjvandehaar

Câu trả lời:


17

đề nghị của terdon sẽ làm việc nhưng tôi đoán của tôi là hiệu quả hơn.

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

Đây là tính toán sự khác biệt giữa thời gian nhất định và thời gian hiện tại tính bằng giây. Nếu số đó là số âm, chúng ta phải thêm giây cho cả ngày (chính xác là 86400) để có được số giây chúng ta phải ngủ và nếu số đó là số nguyên thì chúng ta có thể sử dụng nó.


Điều gì xảy ra nếu đồng hồ hệ thống di chuyển tiến / lùi (ví dụ: ntp).
WhyNotHugo

10

Giả sử nó là một kịch bản shell, điều này sẽ hoạt động:

while [ $(date +%H:%M) != "04:00" ]; do sleep 1; done

Đó là trong 24 giờ. Nếu bạn muốn điều này tiếp tục cả lúc 4:00 AM và 4:00 PM, thay vào đó hãy sử dụng:

while [ $(date +%I:%M) != "04:00" ]; do sleep 1; done

Đây có thể là một lựa chọn. Tôi mới có một ý tưởng. Tôi sẽ trở lại trong một vài phút.
BrainStone

0

Trên OpenBSD , những điều sau đây có thể được sử dụng để thu gọn công việc */55 phút crontab(5)thành một 00giờ (để đảm bảo tạo ra ít email hơn, trong khi thực hiện cùng một nhiệm vụ theo các khoảng thời gian chính xác):

#!/bin/sh -x
for k in $(jot 12 00 55)
  do
  echo $(date) doing stuff
  sleep $(expr $(date -j +%s $(printf %02d $(expr $k + 5))) - $(date -j +%s))
done

Lưu ý rằng thiết kế date(1)cũng sẽ phá vỡ sleep(1)thiết kế trên lần lặp cuối cùng, vì 60phút không phải là thời gian hợp lệ (trừ khi đó là!), Do đó chúng tôi sẽ không phải chờ thêm thời gian trước khi nhận báo cáo email.

Cũng lưu ý rằng nếu một trong các lần lặp lại mất hơn 5 phút được phân bổ cho nó, thì điều đó sleepcũng sẽ thất bại một cách nghiêm trọng bởi thiết kế do không ngủ được (do số âm được hiểu là tùy chọn dòng lệnh, thay vì quấn quanh giờ tiếp theo hoặc thậm chí là vĩnh cửu), do đó đảm bảo rằng công việc của bạn vẫn có thể hoàn thành trong vòng một giờ được phân bổ (ví dụ: nếu chỉ một lần lặp lại mất hơn 5 phút một chút, thì chúng tôi vẫn có thời gian để bắt kịp, mà không cần bất cứ điều gì bao quanh đến giờ tiếp theo).

Điều printf(1)này là cần thiết bởi vì datemong đợi chính xác hai chữ số cho đặc điểm kỹ thuật phút.

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.