Comment vérifier si l'heure actuelle est comprise entre 23h00 et 06h30


9

J'ai du mal à comprendre comment vérifier correctement à partir d'un script bash si l'heure actuelle est comprise entre 23h00 et 06h30. J'essaie d'exécuter une boucle infinie pour vérifier l'heure maintenant et de faire quelque chose si la plage horaire se situe entre 23 h et 6 h 30. Voici ce que j'ai écrit jusqu'à présent, qui ne fonctionne pas le lendemain:

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

Qu'est ce que je fais mal?


"qui ne marche pas le lendemain" ... si vous utilisez les horodatages d'hier 23h00 et 06h30 et ne les mettez jamais à jour ....
muru

Réponses:


17

Si tout ce dont vous avez besoin est de vérifier s'il se HH:MMsitue entre 23h00 et 06h30, n'utilisez pas d'horodatage Unix. Vérifiez simplement les HH:MMvaleurs directement:

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

Remarques:

  • L'heure d' HH:MMentrée sera dans l'ordre lexicographique, vous pouvez donc les comparer directement sous forme de chaînes.
  • Évitez d'utiliser -aou -odans[ ] , utilisez ||et à la &&place.
  • Puisque c'est bash, préférez [[ ]]plutôt [ ], cela rend la vie plus facile.

Pouvez-vous vérifier l'heure actuelle dans un fuseau horaire spécifique? Merci!
tommy.carstensen

1
@ tommy.carstensen vous pouvez dateutiliser un fuseau horaire spécifique en utilisant la TZvariable (par exemple, TZ=Asia/Tokyo dateouTZ=UTC date +%H:%M
muru le

Je vous donnerais un plus supplémentaire juste pour nommer la méthode fireup ()
jbrahy

@jbrahy c'était l'idée d'OP (c'est dans la question)
muru

5

Si vous voulez être plus explicite sur les heures auxquelles vous voulez correspondre, vous pouvez utiliser une casedéclaration. Voici une boucle de 24 heures avec une déclaration de cas à l'intérieur qui indique si l'heure actuelle correspond à votre plage:

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

Pour l'utiliser dans votre script, remplacez simplement les variables par un appel à date:

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

Vous pourriez envisager d'être plus convivial avec votre CPU et de calculer la durée entre (maintenant) et la prochaine heure de démarrage, et sleeppendant cette durée.


Sensationnel. C'est une solution très inattendue et excellente. Merci!
SinaOwolabi

1

Vous pouvez convertir le temps en secondes depuis le début de "ce" jour, puis vérifier que la valeur des secondes est supérieure à 23*60*60(82800) ou inférieure à 6*60*60+30*60(23400).

Pour obtenir des secondes depuis le début de "ce" jour, vous pouvez faire:

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

Et le test serait:

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

0

J'ai une situation similaire. Mon objectif est d'avoir une solution très simple à maintenir pour les geeks non-unix.

Lorsque mon serveur Linux redémarre, il exécute un script qui envoie une alerte. Mais si cela se produit dans le cadre de notre "fenêtre de maintenance" qui est définie entre 23h samedi et 6h dimanche, je ne veux pas envoyer la page, car un redémarrage pendant cette fenêtre est correct (correctifs appliqués, etc.). Je l'ai testé et cela fonctionne comme prévu (pour autant que je sache).

Voici le calendrier pour référence:

      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

Voici mon code de test:

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

Voici la sortie

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
Comme cela semble tenter de répondre à la question, je l'ai laissé, avec quelques modifications. Si vous souhaitez vraiment que quelqu'un examine votre code, je vous suggère codereview.stackexchange.com
Jeff Schaller

Merci Jeff, oui, je cherchais des suggestions, je ne connaissais pas le site de codereview. Merci
Daniel

0

Dans ce cas particulier, une alternative pour simplifier le test consiste à ajouter une heure et à tester une fois pour moins de 07:30

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

-2

Astuce: la réponse de muru ci-dessus a fonctionné pour moi, mais au lieu de || (tuyaux, "ou"), j'ai dû utiliser && ("et" opérateur).

comme ceci: si [["$ currenttime"> "23:00"]] && [["$ currenttime" <"06:30"]]


2
Cela n'a aucun sens. Quelle valeur possible de l'heure actuelle est à la fois supérieure à "23:00" et également inférieure à "06:30"? Indice: il n'y en a pas.
Scott
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.