So überprüfen Sie, ob die aktuelle Zeit zwischen 23:00 und 06:30 Uhr liegt


8

Ich habe Probleme zu verstehen, wie ich anhand eines Bash-Skripts richtig überprüfen kann, ob die aktuelle Zeit zwischen 23:00 und 06:30 Uhr liegt. Ich versuche, eine Endlosschleife auszuführen, um die Uhrzeit jetzt zu überprüfen und etwas zu tun, wenn der Zeitbereich zwischen 23 Uhr und 6:30 Uhr liegt. Folgendes habe ich bisher geschrieben, was am nächsten Tag nicht funktioniert:

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 &
 }

Was mache ich falsch?


"was am nächsten Tag nicht funktioniert" ... wenn Sie die gestrigen Zeitstempel von 23:00 und 06:30 verwenden und diese niemals aktualisieren ...
muru

Antworten:


16

Wenn Sie nur überprüfen müssen, ob HH:MMzwischen 23:00 und 06:30 Uhr liegt, verwenden Sie keine Unix-Zeitstempel. Überprüfen Sie einfach die HH:MMWerte direkt:

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 &
}

Anmerkungen:

  • Die Zeit in HH:MMwird in lexikografischer Reihenfolge angegeben, sodass Sie sie direkt als Zeichenfolgen vergleichen können.
  • Vermeiden Sie die Verwendung von -aoder -oin[ ] , verwenden Sie ||und &&stattdessen.
  • Da dies Bash ist, ziehen [[ ]]Sie es vor [ ], es macht das Leben leichter.

Können Sie die aktuelle Zeit in einer bestimmten Zeitzone überprüfen? Vielen Dank!
Tommy.carstensen

1
@ tommy.carstensen Sie können dateeine bestimmte Zeitzone mit der TZVariablen verwenden (z. B. TZ=Asia/Tokyo dateoderTZ=UTC date +%H:%M
muru

5

Wenn Sie die Zeiten, zu denen Sie übereinstimmen möchten, genauer angeben möchten, können Sie eine caseAnweisung verwenden. Hier ist eine 24-Stunden-Schleife mit einer case-Anweisung, die angibt, ob die aktuelle Zeit Ihrem Bereich entspricht:

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

Um es in Ihrem Skript zu verwenden, ersetzen Sie einfach die Variablen durch einen Aufruf von date:

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

Sie könnten in Betracht ziehen, freundlicher mit Ihrer CPU umzugehen und die Zeitspanne zwischen (jetzt) ​​und der nächsten Startzeit und sleepfür diese Zeitspanne zu berechnen .


Beeindruckend. Dies ist eine sehr unerwartete und großartige Lösung. Vielen Dank!
SinaOwolabi

1

Sie können die Zeit seit Beginn dieses Tages in Sekunden umrechnen und dann überprüfen, ob der Sekundenwert entweder größer als 23*60*60(82800) oder 6*60*60+30*60kleiner als (23400) ist.

Um Sekunden seit dem Beginn "dieses" Tages zu erhalten, können Sie Folgendes tun:

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

Und der Test wäre:

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

0

Ich habe eine ähnliche Situation. Mein Ziel ist es, eine Lösung zu haben, die für Nicht-Unix-Geeks sehr einfach zu warten ist.

Beim Neustart meines Linux-Servers wird ein Skript ausgeführt, das eine Warnung sendet. Wenn dies jedoch als Teil unseres "Wartungsfensters" geschieht, das zwischen Samstag 23 Uhr und Sonntag 6 Uhr definiert ist, möchte ich die Seite nicht senden, da ein Neustart in diesem Fenster in Ordnung ist (Patches angewendet usw.). Ich habe es getestet und es funktioniert wie beabsichtigt (soweit ich das beurteilen kann).

Hier ist der Kalender als Referenz:

      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

Hier ist mein Testcode:

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

Hier ist die Ausgabe

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

1
Da dies zu versuchen scheint, die Frage zu beantworten, habe ich sie mit einigen Änderungen belassen. Wenn Sie wirklich den Wunsch haben, dass jemand Ihren Code überprüft, empfehle ich codereview.stackexchange.com
Jeff Schaller

Danke Jeff, ja, ich habe nach Vorschlägen gesucht. Mir war die Codereview-Site nicht bekannt. Danke
Daniel

0

In diesem speziellen Fall besteht eine Alternative zur Vereinfachung des Tests darin, eine Stunde hinzuzufügen und einmal für weniger als zu testen 07:30

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

-2

Hinweis: Murus Antwort oben hat bei mir funktioniert, aber anstelle von || (Pipes, "oder") musste ich && ("und" Operator) verwenden.

wie folgt: if [["$ currenttime"> "23:00"]] && [["$ currenttime" <"06:30"]]


2
Das macht keinen Sinn. Welcher mögliche Wert der aktuellen Zeit ist sowohl größer als "23:00" als auch kleiner als "06:30"? Hinweis: Es gibt keine.
Scott
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.