Come posso utilizzare una query If-Else in base al giorno della settimana?


10

Problema: devo verificare se oggi è giovedì ed eseguire diverse azioni in base al risultato di questa condizione. Ho provato due approcci diversi:

Ottenere il nome del giorno:

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

Ottenere il giorno Num:

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

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

In entrambi i casi, l'output è NO, anche se dovrebbe essere SÌ. Che c'è?


1
Una nota a margine: quelli ;sarebbero richiesti se avessi thennella stessa riga con if. In questo caso sono ridondanti.
arte

Risposte:


12

Il problema è lo spazio vuoto mancante.

Il codice seguente funzionerà nelle shell il cui [comando incorporato accetta ==come alias per =:

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

Ma tieni a mente (vedi help testin bash):

  • ==non è menzionato ufficialmente, è necessario utilizzarlo =per il confronto delle stringhe
  • -eqè inteso per i test aritmetici decimali (non farà differenza qui, date +%uma date +%dper esempio quando si tratta di confrontare 04e 4che sono numericamente identici ma lessicamente diversi).

Preferirei:

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

Generalmente dovresti preferire l' approccio del numero del giorno , perché ha meno dipendenza dall'impostazione internazionale corrente . Sul mio sistema l'output di date +"%a"è oggi Do.


3

Non trascurare casequale è spesso un modo migliore per fare questo tipo di cose:

Inoltre date +%a, fai attenzione che l'output di dipende dalle impostazioni locali, quindi se ti aspetti i nomi inglesi, lo script smetterà di funzionare se invocato da un utente francese o coreano, ad esempio.

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

Si noti che sopra è uno dei rari casi in cui $(...)non è necessario che siano citati (anche se le virgolette non danneggiano. Come in var="$(...)").


0

Nella stessa idea, uso il seguente pezzo di codice per "disabilitare" un cron prima di un'ora prescelta.
Ovviamente, preferirei modificare il crontab stesso ... se mi venissero concessi i diritti necessari per :)

Ecco un semplice test che interrompe uno script bash a meno che non siamo di notte.

# 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

Perché usare al /usr/bin/testposto del [comando incorporato della shell ?
Stéphane Chazelas,

@ Stéphane Chazelas Non ho usato 3,4,5,6 perché non ho accesso al crontab. ( questa è la seconda riga del mio post :) I nostri server sono gestiti da Claranet e abbiamo già perso una settimana di ticket-ping-pong per ottenere ... un cron funzionante (non scherzando). Quindi evitiamo di incasinare e riaprire i biglietti quando possiamo :) Per questo motivo, abbiamo chiesto un'attività cron oraria anziché giornaliera, e fino a quando tutti i nostri test saranno completati, sarà molto più facile non toccare l'attività, e aggiungi i nostri controlli nello script eseguito.
Balmipour,

Ah ok, scusa, pensavo volessi dire che non avevi il diritto di modificare il cronfile eseguibile rispetto al crontab dell'utente.
Stéphane Chazelas,

@ Stéphane Chazelas Circa la sintassi del test, l'ho preferito su [] o [[]] perché ho provato prima il mio script su qualche altro server, dove potevo usare il crontab. Dopo troppe sorprese con i croni, ho preso l'abitudine di usare il percorso assoluto nei crontab il più possibile. Si potrebbe dire che rende i test brutti e avrà ragione ... ma risponderò comunque che i test di shell sono sempre brutti e che avranno ragione anche ^^ Quello che conta per me era soprattutto avere una risposta che funzionasse con un copia / incolla semplice e includi alcune spiegazioni.
Balmipour,

1
Si noti che -aè deprecato in test. Normalmente, useresti: hour=$(date +%H); if [ "$hour" -gt 2 ] && [ "$hour" -lt 7 ](o hour=`date +%H`se avessi bisogno di essere compatibile con la shell Bourne, che è Solaris 10 e precedenti e forse alcuni rari SCO al giorno d'oggi)
Stéphane Chazelas

0

Per interrompere lo script nel giorno della settimana, elimina solo la riga del giorno:

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

Benvenuto su Unix SE! Non sono sicuro di aver capito bene la tua prima riga. Non sarebbe un if [ "$DAYOFWEEK" -lt 7 ]migliore?
Peter - Ripristina Monica

-1

Per prima cosa dovresti citare l'incarico DAYOFWEEK = "$ (data +% u)"

E devi avere spazi su ciascun lato delle parentesi [e].

Il punto e virgola alla fine della linea è ridondante.


1
Il preventivo non è necessario.
H.-Dirk Schmitt,

Per espandere il commento di @ H.-DirkSchmitt: il motivo per cui non è necessario il preventivo è che l'output non conterrà spazi.
un CVn

@ MichaelKjörling: No - non è mai necessario ;-) Prova l'esempio:a=$(echo 1 2 3); echo $a;
H.-Dirk Schmitt

@ H.-DirkSchmitt a=$(echo "1 2 3"); echo $acon più spazi tra le cifre (StackExchange non mi consente di renderlo un semplice copia-incolla, purtroppo).
un CVn

@ MichaelKjörling - vedi man bash "Se la sostituzione appare tra virgolette doppie, la divisione delle parole e l'espansione del percorso non vengono eseguite sui risultati." Quindi, nel caso della domanda e dell'esempio "1 2 3" non fa alcuna differenza.
H.-Dirk Schmitt,
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.