Як я можу використовувати запит If-Else на основі дня тижня?


10

Проблема: мені потрібно перевірити, чи сьогодні сьогодні четвер, і виконувати різні дії на основі результату цієї умови. Я спробував два різних підходи:

Отримання імені дня:

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

Отримання числа за день:

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

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

В обох випадках вихід НІ, хоча він повинен бути ТАК. Що не так?


1
Побічна примітка: вони ;потрібні, якщо ви thenзнаходитесь в одному рядку if. У цьому випадку вони є зайвими.
манатура

Відповіді:


12

Проблема полягає у відсутньому бланку.

Наступний код буде працювати в оболонках, [вбудована команда яких приймає ==псевдонім для =:

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

Але майте на увазі (див. help testУ bash):

  • ==офіційно не згадується, ви повинні використовувати =для порівняння рядків
  • -eqпризначений для десяткових арифметичних тестів (тут не буде різнитися, date +%uале, date +%dнаприклад, якщо мова йде про порівняння 04і 4які чисельно однакові, але лексично різні).

Я волів би:

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

Як правило, вам слід віддати перевагу підходу до числа днів , оскільки він має меншу залежність від поточного місцеположення . У моїй системі date +"%a"сьогодні є вихід Do.


3

Не забувайте, caseщо часто є кращим способом зробити такі речі:

Також майте на увазі, що результат роботи date +%aлокально залежить, тому якщо ви очікуєте англійських імен, ваш сценарій припинить роботу, коли, наприклад, викликається французький або корейський користувач.

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

Зауважте, що вище - один з рідкісних випадків, коли цього $(...)не потрібно цитувати (хоча цитати не завдадуть шкоди. Те саме, що і в var="$(...)").


0

У цій же ідеї я використовую наступний фрагмент коду, щоб "відключити" крон перед обраною годиною.
Звичайно, я б скоріше змінив сам кронтаб ..., якби мені було надано необхідні права :)

Ось простий тест, який скасовує баш сценарій, якщо ми не вночі.

# 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

Навіщо використовувати /usr/bin/testзамість вбудованої [команди оболонки ?
Стефан Шазелас

@ Stéphane Chazelas Я не використовував 3,4,5,6, тому що не маю доступу до кронтабу. ( це другий рядок моєї публікації :) Нашими серверами керує Claranet, і ми вже втратили тиждень білет-пінг-понгу, щоб отримати ... робочий крон (не жартую). Таким чином, ми уникаємо псування та повторного відкриття квитків, коли зможемо :) З цієї причини ми попросили щогодинну задачу на Cron замість щоденної, і поки всі наші тести не будуть виконані, буде легше не торкатися завдання, і додайте наші елементи керування у виконаний сценарій.
Бальміпур

Ну добре, вибачте, я вважав, що ти мав на увазі, що ти не маєш права змінювати cronвиконуваний файл на відміну від crontab користувача.
Стефан Шазелас

@ Stéphane Chazelas Щодо тестового синтаксису, я віддав перевагу йому над [] або [[]], оскільки спершу спробував свій сценарій на якомусь іншому сервері, де я міг би використовувати кронтаб. Після занадто багатьох сюрпризів із кронами, я придбав звичку використовувати абсолютний шлях у кронтабах якнайбільше. Можна сказати , що це робить тести некрасиво, і буде правий ... але я відповім , що тест оболонки завжди некрасиво в будь-якому випадку, і буде правий теж ^^ Що важливо для мене було головним , щоб отримати відповідь , який буде працювати з проста копія / вставка та включення деяких пояснень.
Бальміпур

1
Зауважте, що -aзастаріле в test. Як правило, ви використовуєте: hour=$(date +%H); if [ "$hour" -gt 2 ] && [ "$hour" -lt 7 ](або hour=`date +%H`якщо вам потрібно було сумісні з оболонкою Борна, тобто Solaris 10 і старших, і, можливо, сьогодні деякі рідкісні угоди ШОС)
Stéphane Chazelas

0

Щоб зупинити сценарій у день тижня, видаліть лише рядок дня:

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

Ласкаво просимо на Unix SE! Я не впевнений, чи правильно я зрозумів ваш перший рядок. Не було б if [ "$DAYOFWEEK" -lt 7 ]краще?
петерх

-1

По-перше, слід процитувати завдання DAYOFWEEK = "$ (дата +% u)"

І вам потрібно мати пробіли на кожній стороні дужок [і].

Напівколона в кінці рядка є зайвою.


1
Цитування не потрібне.
Х.-Дірк Шмітт

Щоб розширити коментар @ H.-DirkSchmitt: причина, чому цитування не потрібне, полягає в тому, що висновок не буде містити пробілів.
CVn

@ MichaelKjörling: Ні - це ніколи не потрібно ;-) Спробуйте приклад:a=$(echo 1 2 3); echo $a;
Х.-Дірк Шмітт

@ H.-DirkSchmitt a=$(echo "1 2 3"); echo $aз кількома пробілами між цифрами (StackExchange не дозволить мені зробити це простим копіюванням та вставкою, на жаль).
CVn

@ MichaelKjörling - див. Man bash "Якщо підміна з'являється в подвійних лапках, розбиття слів і розширення імені не виконуються за результатами". Тож у випадку запитання та прикладу "1 2 3" немає різниці.
Х.-Дірк Шмітт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.