¿Cómo uso una consulta If-Else basada en el día de la semana?

10

Problema: necesito verificar si hoy es jueves y realizar diferentes acciones en función del resultado de esta condición. Intenté dos enfoques diferentes:

Obteniendo el nombre del día:

DAYOFWEEK=$(date +"%a")
echo DAYOFWEEK: $DAYOFWEEK
if ["$DAYOFWEEK" == "Thu"]; 
then   
   echo YES
else
    echo NO
fi

Obteniendo el día Num:

DAYOFWEEK=$(date +"%u")
echo DAYOFWEEK: $DAYOFWEEK

if ["$DAYOFWEEK" == 4]; 
then
   echo YES
else
   echo NO
fi

En ambos casos, la salida es NO, aunque debería ser SÍ. ¿Qué está mal?

Swagatika
fuente
1
Una nota al margen: esos ;serían necesarios si tuviera thenen la misma línea con if. En este caso son redundantes.
manatwork

Respuestas:

12

El problema es el espacio en blanco que falta.

El siguiente código funcionará en shells cuyo [comando incorporado acepta ==como un alias para =:

if [ "$DAYOFWEEK" == 4 ];  then    echo YES; else    echo NO; fi

Pero tenga en cuenta (ver help testen bash):

  • ==no se menciona oficialmente, debe usar =para comparar cadenas
  • -eqestá destinado a pruebas aritméticas decimales (no hará una diferencia aquí, date +%upero lo haría, date +%dpor ejemplo, cuando se trata de comparar 04y 4que son numéricamente iguales pero léxicamente diferentes).

Yo preferiría:

 if [ "${DAYOFWEEK}" -eq 4 ];  then    echo YES; else    echo NO; fi

En general, debe preferir el enfoque de número de día , ya que tiene menos dependencia de la configuración regional actual . En mi sistema, la salida date +"%a"es hoy Do.

H.-Dirk Schmitt
fuente
3

No pase por alto casecuál es a menudo una mejor manera de hacer este tipo de cosas:

También tenga en cuenta que la salida de date +%adepende de la configuración regional, por lo que si espera los nombres en inglés, su script dejará de funcionar cuando lo invoque un usuario francés o coreano, por ejemplo.

case $(LC_ALL=C date +%a) in
   (Mon) echo first day of the week;;
   (Thu) do-something;;
   (Sat|Sun) echo week-end;;
   (*) echo any other day;; # last ;; not necessary but doesn't harm
esac

Tenga en cuenta que arriba es uno de los raros casos en los que $(...)no es necesario citarlo (aunque las citas no dañarán. Igual que en var="$(...)").

Stéphane Chazelas
fuente
0

En la misma idea, uso el siguiente código para "deshabilitar" un cron antes de una hora elegida.
Por supuesto, preferiría modificar el crontab en sí ... si se me otorgan los derechos necesarios para :)

Aquí hay una prueba simple que aborta un script bash a menos que estemos de noche.

# Delay or restrict execution.
# Here, we quit unless hour is greater than (gt) 2 and (-a) lower than (lt) 7
# i.e. execution happens only at 3,4,5&6 o'clock.
if  /usr/bin/test `date '+%H'` -gt 2 -a `date '+%H'` -lt 7; then
  echo LETS_START_PROCESSING;
else
  exit;
fi

#Put job here
Balmipour
fuente
¿Por qué usar en /usr/bin/testlugar del [comando incorporado del shell ?
Stéphane Chazelas
@ Stéphane Chazelas No utilicé 3,4,5,6 porque no tengo acceso al crontab. ( esta es la segunda línea de mi publicación :) Nuestros servidores son administrados por Claranet, y ya perdimos una semana de ticket-ping-pong para obtener ... un cron que funcione (no es broma). Por lo tanto, evitamos estropear y volver a abrir boletos cuando podamos :) Por esa razón, solicitamos una tarea cron por hora en lugar de diariamente, y hasta que se realicen todas nuestras pruebas, será mucho más fácil no tocar la tarea, y agregue nuestros controles en el script ejecutado.
Balmipour
Ah, ok, lo siento, pensé que querías decir que no tenías derecho a modificar el cronejecutable en lugar del crontab del usuario.
Stéphane Chazelas
@ Stéphane Chazelas Acerca de la sintaxis de prueba, la preferí a [] o [[]] porque primero probé mi script en otro servidor, donde pude usar el crontab. Después de demasiadas sorpresas con crons, tuve la costumbre de usar la ruta absoluta en crontabs tanto como sea posible. Uno puede decir que hace que las pruebas sean feas, y tendrá razón ... pero responderé que la prueba de shell siempre es fea de todos modos, y también será correcta ^^ Lo que me importaba era tener una respuesta que funcionara con un copiar / pegar simple e incluir algunas explicaciones.
Balmipour
1
Tenga en cuenta que -aestá en desuso en test. De manera estándar, usaría: hour=$(date +%H); if [ "$hour" -gt 2 ] && [ "$hour" -lt 7 ](o hour=`date +%H`si necesita ser compatible con el shell Bourne, es Solaris 10 y versiones anteriores y tal vez algunos SCO unices raros hoy en día)
Stéphane Chazelas
0

Para detener el script en el día de la semana, solo elimine la línea del día:

DAYOFWEEK=$(date +"%u")
echo "$DAYOFWEEK";
if [ "$DAYOFWEEK" == 1 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 2 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 3 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 4 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 5 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 6 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 7 ]; then exit; else echo; fi
Daniel FR César
fuente
¡Bienvenido al Unix SE! No estoy seguro si entendí tu primera línea correctamente. ¿No sería if [ "$DAYOFWEEK" -lt 7 ]mejor?
peterh - Restablece a Monica
-1

En primer lugar, debe citar la tarea DAYOFWEEK = "$ (fecha +% u)"

Y debe tener espacios a cada lado de los corchetes [y].

El punto y coma al final de la línea es redundante.

Johan
fuente
1
La cita no es necesaria.
H.-Dirk Schmitt
Para ampliar el comentario de @ H.-DirkSchmitt: la razón por la que no se necesita la cita es que la salida no contendrá ningún espacio.
un CVn
@ MichaelKjörling: No, nunca es necesario ;-) Pruebe el ejemplo:a=$(echo 1 2 3); echo $a;
H.-Dirk Schmitt
@ H.-DirkSchmitt a=$(echo "1 2 3"); echo $acon múltiples espacios entre los dígitos (StackExchange no me permite convertirlo en un simple copiar y pegar, desafortunadamente).
un CVn
@ MichaelKjörling - ver man bash "Si la sustitución aparece entre comillas dobles, la división de palabras y la expansión del nombre de ruta no se realizan en los resultados". Por lo tanto, en el caso de la pregunta y el ejemplo "1 2 3" no hay diferencia.
H.-Dirk Schmitt