Cómo verificar si la hora actual es entre las 23:00 y las 06:30

9

Tengo problemas para comprender cómo verificar correctamente desde un script bash si la hora actual es entre las 23:00 y las 06:30. Estoy tratando de ejecutar un ciclo infinito para verificar la hora ahora y hacer algo si el rango de tiempo es entre las 11 p.m. y las 6:30 a.m. Esto es lo que he escrito hasta ahora, que no funciona al día siguiente:

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

¿Que estoy haciendo mal?

SinaOwolabi
fuente
"el que no trabaja el día siguiente" ... si se utiliza a 23:00 y de 06:30 a marcas de tiempo de ayer y nunca actualizar los ....
Muru

Respuestas:

17

Si todo lo que necesita es verificar si HH:MMes entre las 23:00 y las 06:30, no use las marcas de tiempo de Unix. Simplemente verifique los HH:MMvalores directamente:

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

Notas:

  • El tiempo HH:MMserá en orden lexicográfico, por lo que puede compararlos directamente como cadenas.
  • Evite usar -ao -oen[ ] , use ||y en su &&lugar.
  • Como esto es bash, preferir [[ ]]sobre [ ], hace la vida más fácil.
muru
fuente
¿Puedes consultar la hora actual en una zona horaria específica? ¡Gracias!
tommy.carstensen
1
@ tommy.carstensen puede dateusar una zona horaria específica usando la TZvariable (por ejemplo, TZ=Asia/Tokyo dateoTZ=UTC date +%H:%M
muru
Te daría una ventaja adicional solo por nombrar el método fireup ()
jbrahy
@jbrahy esa fue la idea de OP (está en la pregunta)
muru
5

Si desea ser más explícito acerca de las veces que desea coincidir, puede usar una casedeclaración. Aquí hay un ciclo de 24 horas con una declaración de caso dentro que indica si la hora actual coincide con su rango:

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

Para usarlo en su script, simplemente reemplace las variables con una llamada a date:

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

Puede considerar ser más amigable con su CPU y calcular la cantidad de tiempo entre (ahora) y la próxima hora de inicio, y sleepdurante esa cantidad de tiempo.

Jeff Schaller
fuente
Guau. Esta es una solución muy inesperada y excelente. ¡Gracias!
SinaOwolabi
1

Puede convertir el tiempo a segundos desde el inicio de "este" día y luego verificar que el valor de los segundos sea mayor que 23*60*60(82800) o menor que 6*60*60+30*60(23400).

Para obtener segundos desde el comienzo de "este" día puede hacer:

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

Y la prueba sería:

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

Tengo una situación similar. Mi objetivo es tener una solución que sea muy simple para los geeks que no son Unix.

Cuando mi servidor Linux se reinicia, ejecuta un script que envía una alerta. Pero si esto sucede como parte de nuestra "Ventana de mantenimiento", que se define entre las 11 p. M. El sábado y las 6 a. M. Del domingo, no quiero enviar la página, porque un reinicio durante esta ventana está bien (parches aplicados, etc.). Lo he probado y funciona según lo previsto (hasta donde puedo decir).

Aquí está el calendario de referencia:

      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

Aquí está mi código de prueba:

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

Aquí está la salida

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
fuente
1
Como esto parece intentar responder la pregunta, la dejé con algunas modificaciones. Si realmente desea que alguien revise su código, le sugiero codereview.stackexchange.com
Jeff Schaller
Gracias Jeff, sí, estaba buscando sugerencias. No conocía el sitio de codereview. Gracias
Daniel
0

En este caso particular, una alternativa para simplificar la prueba es agregar una hora y probar una vez por menos de 07:30

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

Sugerencia: la respuesta de muru anterior funcionó para mí, pero en lugar de || (tuberías "o"), tuve que usar && ("y" operador).

así: si [["$ currenttime"> "23:00"]] && [["$ currenttime" <"06:30"]]

ChaLinux
fuente
2
Eso no tiene ningún sentido. Lo posible valor de CurrentTime es tanto mayor que “23:00” y también menor que “6:30”? Sugerencia: no hay ninguna.
Scott,