Wie verwende ich eine If-Else-Abfrage basierend auf dem Wochentag?


10

Problem: Ich muss überprüfen, ob heute Donnerstag ist, und basierend auf dem Ergebnis dieser Bedingung verschiedene Aktionen ausführen. Ich habe zwei verschiedene Ansätze ausprobiert:

Den Tagesnamen erhalten:

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

Den Tag bekommen Num:

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

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

In beiden Fällen ist der Ausgang NEIN, obwohl er JA sein sollte. Was ist falsch?


1
Eine Randnotiz: Diese ;wären erforderlich, wenn Sie thenin der gleichen Zeile mit hätten if. In diesem Fall sind sie redundant.
Manatwork

Antworten:


12

Das Problem ist das fehlende Leerzeichen.

Der folgende Code funktioniert in Shells, deren [eingebauter Befehl ==als Alias ​​für akzeptiert wird =:

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

Aber denken Sie daran (siehe help testin bash):

  • ==wird nicht offiziell erwähnt, sollten Sie =für den String-Vergleich verwenden
  • -eqist für dezimale arithmetische Tests gedacht (macht hier keinen Unterschied date +%u, würde aber date +%dzum Beispiel beim Vergleichen 04und 4die numerisch gleich, aber lexikalisch unterschiedlich sind).

Ich würde bevorzugen:

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

Im Allgemeinen sollten Sie den Tag lieber Zahl Ansatz, weil es weniger Abhängigkeit der aktuellen hat locale . Auf meinem System ist die Ausgabe von date +"%a"heute Do.


3

Übersehen Sie nicht, casewas oft ein besserer Weg ist, um solche Dinge zu tun:

Beachten Sie auch, dass die Ausgabe von vom date +%aGebietsschema abhängig ist. Wenn Sie also die englischen Namen erwarten, funktioniert Ihr Skript nicht mehr, wenn es beispielsweise von einem französischen oder koreanischen Benutzer aufgerufen wird.

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

Beachten Sie, dass oben einer der seltenen Fälle ist, in denen $(...)dies nicht in Anführungszeichen gesetzt werden muss (obwohl Anführungszeichen nicht schaden. Wie in var="$(...)").


0

In der gleichen Idee verwende ich den folgenden Code, um einen Cron vor einer ausgewählten Stunde zu "deaktivieren".
Natürlich würde ich lieber den Crontab selbst ändern ... wenn mir die erforderlichen Rechte für :) gewährt würden

Hier ist ein einfacher Test, der ein Bash-Skript abbricht, es sei denn, wir sind nachts.

# 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

Warum /usr/bin/testanstelle des integrierten [Befehls der Shell verwenden ?
Stéphane Chazelas

@ Stéphane Chazelas Ich habe 3,4,5,6 nicht verwendet, weil ich keinen Zugang zum Crontab habe. ( Dies ist die zweite Zeile meines Beitrags :) Unsere Server werden von Claranet verwaltet, und wir haben bereits eine Woche Ticket-Ping-Pong verloren, um ... einen funktionierenden Cron zu bekommen (kein Scherz). Wir vermeiden es also, Tickets zu vermasseln und wieder zu öffnen, wenn wir können :) Aus diesem Grund haben wir statt täglich um eine stündliche Cron-Aufgabe gebeten, und bis alle unsere Tests abgeschlossen sind, wird es viel einfacher sein, die Aufgabe nicht zu berühren, und Fügen Sie unsere Steuerelemente in das ausgeführte Skript ein.
Balmipour

Ah OK, sorry, ich dachte, Sie meinten, Sie hätten nicht das Recht, die cronausführbare Datei im Gegensatz zur Crontab des Benutzers zu ändern .
Stéphane Chazelas

@ Stéphane Chazelas über den Test Syntax, zog ich es über [] oder [[]] , weil ich zum ersten Mal meines Skript auf einem anderen Server versuche, wo ich kann den crontab verwenden. Nach zu vielen Überraschungen mit Cron habe ich mir angewöhnt, den absoluten Pfad in Crontabs so oft wie möglich zu verwenden. Man kann sagen, es macht Tests hässlich und wird richtig sein ... aber ich werde antworten, dass Shell-Tests sowieso immer hässlich sind und auch richtig sein werden ^^ Was für mich wichtig war, war meistens eine Antwort, die mit a funktionieren würde einfaches Kopieren / Einfügen und einige Erklärungen.
Balmipour

1
Beachten Sie, dass -ain veraltet ist test. Standardmäßig würden Sie Folgendes verwenden: hour=$(date +%H); if [ "$hour" -gt 2 ] && [ "$hour" -lt 7 ](oder hour=`date +%H`wenn Sie mit der Bourne-Shell kompatibel sein müssten, dh Solaris 10 und älter und möglicherweise einige seltene SCO-Unices heutzutage)
Stéphane Chazelas

0

Um das Skript am Wochentag zu stoppen, löschen Sie nur die Zeile des Tages:

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

Willkommen auf der Unix SE! Ich bin mir nicht sicher, ob ich Ihre erste Zeile richtig verstanden habe. Wäre nicht if [ "$DAYOFWEEK" -lt 7 ]besser?
Peter

-1

Zunächst sollten Sie die Zuordnung DAYOFWEEK = "$ (Datum +% u)" angeben.

Und Sie müssen auf jeder Seite der Klammern [und] Leerzeichen haben.

Das Semikolon am Ende der Zeile ist redundant.


1
Das Zitat wird nicht benötigt.
H.-Dirk Schmitt

Um den Kommentar von @ H.-DirkSchmitt zu erweitern: Der Grund, warum das Zitat nicht benötigt wird, ist, dass die Ausgabe keine Leerzeichen enthält.
ein CVn

@ MichaelKjörling: Nein - es wird nie benötigt ;-) Versuchen Sie das Beispiel:a=$(echo 1 2 3); echo $a;
H.-Dirk Schmitt

@ H.-DirkSchmitt a=$(echo "1 2 3"); echo $amit mehreren Leerzeichen zwischen den Ziffern (StackExchange lässt mich leider nicht einfach kopieren und einfügen).
ein CVn

@ MichaelKjörling - siehe man bash "Wenn die Ersetzung in doppelten Anführungszeichen steht, werden die Ergebnisse nicht in Wortaufteilung und Pfadnamenerweiterung umgewandelt." So macht es bei der Frage und dem Beispiel "1 2 3" keinen Unterschied.
H.-Dirk Schmitt
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.