Cara memeriksa apakah waktu saat ini antara 23:00 dan 06:30

9

Saya mengalami kesulitan memahami cara memeriksa dengan benar dari skrip bash jika waktu saat ini adalah antara 23:00 dan 06:30. Saya mencoba menjalankan infinite loop untuk memeriksa waktu sekarang, dan melakukan sesuatu jika rentang waktunya antara 11 malam dan 6:30 pagi. Inilah yang telah saya tulis sejauh ini, yang tidak berfungsi pada hari berikutnya:

fireup()
{

 local starttime=$(date --date="23:00" +"%s")
 local endtime=$(date --date="06:30" +"%s")

 while :; do
     local currenttime=$(date +%s)
     if [ "$currenttime" -ge "$starttime" -a "$currenttime" -ge "$endtime" ]; then
        do_something
     else
         do_something_else
     fi
     test "$?" -gt 128 && break
     local currenttime=$(date +%s)
 done &
 }

Apa yang saya lakukan salah?

SinaOwolabi
sumber
"yang tidak berfungsi pada hari berikutnya" ... jika Anda menggunakan cap waktu 23:00 dan 06:30 kemarin dan tidak pernah memperbarui mereka ....
muru

Jawaban:

17

Jika yang Anda butuhkan adalah memeriksa apakah HH:MMantara 23:00 dan 06:30, maka jangan gunakan cap waktu Unix. Cukup periksa HH:MMnilai secara langsung:

fireup()
{  
  while :; do
   currenttime=$(date +%H:%M)
   if [[ "$currenttime" > "23:00" ]] || [[ "$currenttime" < "06:30" ]]; then
     do_something
   else
     do_something_else
   fi
   test "$?" -gt 128 && break
  done &
}

Catatan:

  • Waktu masuk HH:MMakan berada dalam urutan leksikografis, sehingga Anda dapat langsung membandingkannya sebagai string.
  • Hindari menggunakan -aatau -omasuk[ ] , gunakan ||dan &&sebagai gantinya.
  • Karena ini bash, lebih disukai [[ ]]daripada [ ], itu membuat hidup lebih mudah.
muru
sumber
Bisakah Anda memeriksa waktu saat ini di zona waktu tertentu? Terima kasih!
tommy.carstensen
1
@ tommy.carstensen Anda bisa datemenggunakan zona waktu tertentu menggunakan TZvariabel (misalnya, TZ=Asia/Tokyo dateatauTZ=UTC date +%H:%M
muru
Saya akan memberi Anda plus tambahan hanya untuk penamaan metode fireup ()
jbrahy
@jbrahy itu ide OP (ada dalam pertanyaan)
muru
5

Jika Anda ingin lebih eksplisit tentang waktu yang ingin Anda cocokkan, Anda bisa menggunakan casepernyataan. Berikut adalah loop 24 jam dengan pernyataan kasus di dalamnya yang menunjukkan apakah waktu saat ini cocok dengan rentang Anda:

for hh in {00..23}
do
  for mm in {00..59}
  do
    case $hh:$mm in
        (23:*)        echo YES $hh:$mm;;
        (0[012345]:*) echo YES $hh:$mm;;
        (06:[012]*)   echo YES $hh:$mm;;
        (*)           echo  NO $hh:$mm;;
    esac
  done
done

Untuk menggunakannya dalam skrip Anda, cukup ganti variabel dengan panggilan ke date:

case $(date +%H:%M) in
    (23:*)        echo YES;;
    (0[012345]:*) echo YES;;
    (06:[012]*)   echo YES;;
    (*)           echo NO;;
esac

Anda mungkin mempertimbangkan untuk lebih bersahabat dengan CPU Anda dan menghitung jumlah waktu antara (sekarang) dan waktu mulai berikutnya, dan sleepuntuk jumlah waktu tersebut.

Jeff Schaller
sumber
Wow. Ini adalah solusi yang sangat tak terduga dan hebat. Terima kasih!
SinaOwolabi
1

Anda dapat mengonversi waktu ke detik sejak awal hari "ini" dan kemudian memeriksa bahwa nilai detik lebih besar dari 23*60*60(82800) atau lebih rendah dari 6*60*60+30*60(23400).

Untuk mendapatkan detik sejak awal hari "ini" dapat Anda lakukan:

secsSinceMidnight=$(( $(date +%s) - $(date -d '00:00:00' +%s) ))

Dan tesnya adalah:

[[ $secsSinceMidnight -lt 23400 || $secsSinceMidnight -gt 82800 ]] && echo YES
Ishak
sumber
0

Saya memiliki situasi yang sama. Tujuan saya adalah memiliki solusi yang sangat sederhana untuk dipelihara oleh Geeks non-unix.

Ketika server Linux saya restart, ia menjalankan skrip yang mengirimkan peringatan. Tetapi jika ini terjadi sebagai bagian dari "Jendela Perawatan" kami yang didefinisikan antara jam 11 malam Sabtu dan 6 pagi hari Minggu, saya tidak ingin mengirim halaman, karena memulai ulang selama jendela ini adalah Oke (tambalan diterapkan, dll.). Saya telah mengujinya dan berfungsi sebagaimana mestinya (sejauh yang saya tahu).

Berikut adalah kalender untuk referensi:

      June 2018
Su Mo Tu We Th Fr Sa
                1  2
 3  4  5  6  7  8  9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Ini kode pengujian saya:

FMT='+%k:%a' # i.e. Sat:23 for Saturday at 11pm local time

TESTDATE1=$(date -d '2018-06-23 14:30:00' $FMT)
TESTDATE2=$(date -d '2018-06-23 23:59:59' $FMT)
TESTDATE3=$(date -d '2018-06-24 00:00:00' $FMT)
TESTDATE4=$(date -d '2018-06-24 05:59:59' $FMT)
TESTDATE5=$(date -d '2018-06-24 08:01:00' $FMT)

for VAL in "${TESTDATE1}" $TESTDATE2 $TESTDATE3 $TESTDATE4 $TESTDATE5
do

    #extract the 24 hour value and the day
    HH="$(echo ${VAL} | cut -d':' -f1)"
    DAY="$(echo ${VAL} | cut -d':' -f2)"

    echo Testing $VAL  $HH  $DAY

    if [[ "$DAY" = "Sat" && $HH -ge 23 ]]; then
            echo '    Shhhh People are trying to sleep ... Sat window'
    elif [[ "$DAY" = "Sun" && $HH -le 6 ]]; then
            echo '    People are trying to sleep ... Sun window'
    else
            echo '    PAGE SOMEONE - time is outside the Maintenance Window'
    fi

done

Ini outputnya

Testing 14:Sat 14 Sat
    PAGE SOMEONE - time is outside the Maintenance Window
Testing 23:Sat 23 Sat
    Shhhh People are trying to sleep ... Sat window
Testing 0:Sun 0 Sun
    People are trying to sleep ... Sun window
Testing 5:Sun 5 Sun
    People are trying to sleep ... Sun window
Testing 8:Sun 8 Sun
    PAGE SOMEONE - time is outside the Maintenance Window
Daniel
sumber
1
Karena ini tampaknya mencoba menjawab pertanyaan, saya meninggalkannya, dengan beberapa pengeditan. Jika Anda benar-benar memiliki keinginan untuk meminta seseorang meninjau kode Anda, saya sarankan codereview.stackexchange.com
Jeff Schaller
Terima kasih Jeff, ya, saya mencari saran. Saya tidak mengetahui situs codereview. Terima kasih
Daniel
0

Dalam kasus khusus ini, alternatif untuk membuat tes lebih sederhana adalah dengan menambahkan satu jam dan menguji sekali kurang dari 07:30

if [[ $(date -d "now + 60 minutes" +'%H:%M') < "07:30" ]]
    then echo "wake up"
else
    echo "Zzzzzz"
fi
bu5hman
sumber
-2

Petunjuk: jawaban muru di atas bekerja untuk saya, tetapi bukannya || (pipa, "atau"), saya harus menggunakan && ("dan" operator).

seperti ini: jika [["$ currenttime"> "23:00"]] && [["$ currenttime" <"06:30"]]

ChaLinux
sumber
2
Itu tidak masuk akal. Apa mungkin nilai currenttime adalah baik lebih besar dari “23:00” dan juga kurang dari “06:30”? Petunjuk: tidak ada.
Scott