Comment utiliser une requête If-Else basée sur le jour de la semaine?

10

Problème: je dois vérifier si aujourd'hui est jeudi et effectuer différentes actions en fonction du résultat de cette condition. J'ai essayé deux approches différentes:

Obtenir le nom du jour:

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

Obtenir le nombre de jours:

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

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

Dans les deux cas, la sortie est NON, même si elle doit être OUI. Qu'est-ce qui ne va pas?

Swagatika
la source
1
Une note latérale: celles- ;ci seraient nécessaires si vous aviez thendans la même ligne que if. Dans ce cas, ils sont redondants.
manatwork

Réponses:

12

Le problème est le blanc manquant.

Le code suivant fonctionnera dans des shells dont la [commande intégrée accepte ==comme alias pour =:

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

Mais gardez à l'esprit (voir help testen bash):

  • ==n'est pas officiellement mentionné, vous devez utiliser =pour comparer les chaînes
  • -eqest destiné à des tests arithmétiques décimaux (ne fera pas de différence ici date +%umais le serait date +%dpar exemple lorsqu'il s'agit de comparer 04et 4qui sont numériquement les mêmes mais lexicalement différents).

Je préférerais:

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

En règle générale, vous devriez préférer l' approche du nombre de jours , car elle dépend moins des paramètres régionaux actuels . Sur mon système, la sortie de date +"%a"est aujourd'hui Do.

H.-Dirk Schmitt
la source
3

Ne casenégligez pas ce qui est souvent une meilleure façon de faire ce genre de choses:

Sachez également que la sortie de date +%adépend des paramètres régionaux, donc si vous attendez les noms anglais, votre script cessera de fonctionner lorsqu'il sera invoqué par un utilisateur français ou coréen par exemple.

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

Notez que ci-dessus est l'un des rares cas où cela $(...)n'a pas besoin d'être cité (bien que les citations ne nuiront pas. Identique à var="$(...)").

Stéphane Chazelas
la source
0

Dans la même idée, j'utilise le morceau de code suivant pour "désactiver" un cron avant une heure choisie
Bien sûr, je préférerais modifier le crontab lui-même ... si on m'accordait les droits nécessaires pour :)

Voici un test simple qui abandonne un script bash sauf si nous sommes la nuit.

# 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
la source
Pourquoi utiliser à la /usr/bin/testplace de la [commande intégrée du shell ?
Stéphane Chazelas
@ Stéphane Chazelas Je n'ai pas utilisé 3,4,5,6 car je n'ai pas accès à la crontab. ( c'est la 2ème ligne de mon post :) Nos serveurs sont gérés par Claranet, et nous avons déjà perdu une semaine de ticket-ping-pong pour obtenir ... un cron fonctionnel (sans blague). Nous évitons donc de gâcher et de rouvrir les tickets lorsque nous le pouvons :) Pour cette raison, nous avons demandé une tâche cron toutes les heures au lieu de tous les jours, et jusqu'à ce que tous nos tests soient terminés, il sera beaucoup plus facile de ne pas toucher à la tâche, et ajoutez nos contrôles dans le script exécuté.
Balmipour
Ah OK, désolé, je pensais que vous vouliez dire que vous n'aviez pas le droit de modifier l' cronexécutable par opposition à la crontab de l'utilisateur.
Stéphane Chazelas
@ Stéphane Chazelas À propos de la syntaxe du test, je l'ai préférée à [] ou [[]] car j'ai d'abord essayé mon script sur un autre serveur, où je pouvais utiliser la crontab. Après trop de surprises avec crons, j'ai pris l'habitude d'utiliser autant que possible le chemin absolu dans les crontabs. On peut dire que cela rend les tests moches et qu'ils auront raison ... mais je répondrai que les tests shell sont toujours moches de toute façon, et ils le seront aussi ^^ Ce qui m'importe, c'est surtout d'avoir une réponse qui fonctionnerait avec un copier / coller simple, et inclure quelques explications.
Balmipour
1
Notez que -ac'est déconseillé dans test. En règle générale, vous utiliseriez: hour=$(date +%H); if [ "$hour" -gt 2 ] && [ "$hour" -lt 7 ](ou hour=`date +%H`si vous deviez être compatible avec le shell Bourne, c'est-à-dire Solaris 10 et plus ancien et peut-être quelques rares unités SCO de nos jours)
Stéphane Chazelas
0

Pour arrêter le script le jour de la semaine, supprimez uniquement la ligne du jour:

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
la source
Bienvenue sur l'Unix SE! Je ne sais pas si j'ai bien compris votre première ligne. Ce ne serait pas if [ "$DAYOFWEEK" -lt 7 ]mieux?
peterh
-1

Tout d'abord, vous devez citer l'affectation DAYOFWEEK = "$ (date +% u)"

Et vous devez avoir des espaces de chaque côté des crochets [et].

Le point-virgule à la fin de la ligne est redondant.

Johan
la source
1
Le devis n'est pas nécessaire.
H.-Dirk Schmitt
Pour développer le commentaire de @ H.-DirkSchmitt: la raison pour laquelle la citation n'est pas nécessaire est que la sortie ne contiendra aucun espace.
un CVn
@ MichaelKjörling: Non - ce n'est jamais nécessaire ;-) Essayez l'exemple:a=$(echo 1 2 3); echo $a;
H.-Dirk Schmitt
@ H.-DirkSchmitt a=$(echo "1 2 3"); echo $aavec plusieurs espaces entre les chiffres (StackExchange ne me laisse pas en faire un simple copier-coller, malheureusement).
un CVn
@ MichaelKjörling - see man bash "Si la substitution apparaît entre guillemets, le fractionnement des mots et l'expansion des noms de chemin ne sont pas effectués sur les résultats." Cela ne fait donc aucune différence dans le cas de la question et de l'exemple "1 2 3".
H.-Dirk Schmitt