Come verificare se l'ora corrente è tra le 23:00 e le 06:30


9

Ho difficoltà a capire come controllare correttamente da uno script bash se l'ora corrente è tra le 23:00 e le 06:30. Sto cercando di eseguire un ciclo infinito per controllare l'ora e fare qualcosa se l'intervallo di tempo è compreso tra le 23:00 e le 6:30. Ecco cosa ho scritto finora, che non funziona il giorno successivo:

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

Cosa sto facendo di sbagliato?


"che non funziona il giorno successivo" ... se usi i timestamp di ieri alle 23:00 e alle 06:30 e non aggiorni mai quelli ...
muru,

Risposte:


17

Se tutto ciò che serve è verificare se HH:MMè compreso tra le 23:00 e le 06:30, non utilizzare i timestamp Unix. Controlla HH:MMdirettamente i valori:

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

Appunti:

  • Il tempo HH:MMsarà nell'ordine lessicografico, quindi puoi confrontarli direttamente come stringhe.
  • Evita di usare -ao -odentro[ ] , usa ||e &&invece.
  • Dal momento che questo è bash, preferisco [[ ]]oltre [ ], semplifica la vita.

Puoi controllare l'ora corrente in un fuso orario specifico? Grazie!
tommy.carstensen,

1
@ tommy.carstensen puoi dateusare un fuso orario specifico usando la TZvariabile (es. TZ=Asia/Tokyo dateoppureTZ=UTC date +%H:%M
muru

Ti darei un extra in più solo per la denominazione del metodo fireup ()
jbrahy

@jbrahy è stata un'idea di OP (è nella domanda)
muru,

5

Se vuoi essere più esplicito sui tempi in cui vuoi abbinare, puoi usare una casedichiarazione. Ecco un ciclo di 24 ore con all'interno un'istruzione case che indica se l'ora corrente corrisponde al tuo intervallo:

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

Per usarlo nel tuo script, basta sostituire le variabili con una chiamata a date:

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

Potresti considerare di essere più amichevole con la tua CPU e calcolare la quantità di tempo tra (ora) e l'ora di inizio successiva e sleepper quella quantità di tempo.


Wow. Questa è una soluzione molto inaspettata e ottima. Grazie!
SinaOwolabi,

1

È possibile convertire il tempo in secondi dall'inizio di "questo" giorno e quindi verificare che il valore dei secondi sia maggiore di 23*60*60(82800) o inferiore a 6*60*60+30*60(23400).

Per ottenere secondi dall'inizio del giorno "this" puoi fare:

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

E il test sarebbe:

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

0

Ho una situazione simile. Il mio obiettivo è quello di avere una soluzione che sia molto semplice da mantenere per i fanatici non unix.

Quando il mio server Linux si riavvia, esegue uno script che invia un avviso. Ma se questo accade come parte della nostra "Finestra di manutenzione" che è definita tra le 23:00 di sabato e le 6:00 di domenica, non voglio inviare la pagina, perché un riavvio durante questa finestra è OK (patch applicate, ecc.). L'ho provato e funziona come previsto (per quanto ne so).

Ecco il calendario di riferimento:

      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

Ecco il mio codice di prova:

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

Ecco l'output

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
Dal momento che questo sembra tentare di rispondere alla domanda, l'ho lasciato, con alcune modifiche. Se desideri davvero che qualcuno riveda il tuo codice, suggerirei codereview.stackexchange.com
Jeff Schaller

Grazie Jeff, sì, stavo cercando suggerimenti. Non ero a conoscenza del sito codereview. Grazie
Daniel,

0

In questo caso particolare, un'alternativa per semplificare il test è aggiungere un'ora e testare una volta per meno di 07:30

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

-2

Suggerimento: la risposta di Muru sopra ha funzionato per me, ma invece di || (pipe, "o"), ho dovuto usare && ("e" operatore).

in questo modo: if [["$ currenttime"> "23:00"]] && [["$ currenttime" <"06:30"]]


2
Non ha alcun senso. Quale possibile valore dell'ora corrente è maggiore sia di "23:00" che anche di "06:30"? Suggerimento: non ce ne sono.
Scott,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.