Как использовать запрос If-Else, основанный на дне недели?


10

Проблема: мне нужно проверить, не сегодня ли четверг, и выполнить различные действия в зависимости от результата этого условия. Я попробовал два разных подхода:

Получение названия дня:

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

Начало дня Num:

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

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

В обоих случаях выходной сигнал НЕТ, хотя он должен быть ДА. Что не так?


1
Примечание: они ;потребуются, если вы будете thenв одной строке с if. В этом случае они являются избыточными.
manatwork

Ответы:


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

В той же идее я использую следующий фрагмент кода для «отключения» cron до выбранного часа.
Конечно, я бы предпочел изменить сам crontab ... если бы мне были предоставлены необходимые права :)

Вот простой тест, который прерывает скрипт bash, если мы не на ночь.

# 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, потому что у меня нет доступа к crontab. ( это вторая строка моего поста :) Нашими серверами управляет Кларанет, и мы уже потеряли неделю билета на пинг-понг, чтобы получить ... рабочий крон (не шучу). Поэтому мы избегаем путаницы и повторного открытия билетов, когда можем :) По этой причине мы просили ежечасное задание cron вместо ежедневного, и до тех пор, пока все наши тесты не будут выполнены, будет гораздо проще не трогать задачу, и добавьте наши элементы управления в выполненный скрипт.
Balmipour

Ах, хорошо, извините, я думал, что вы имели в виду, что у вас нет права изменять cronисполняемый файл в отличие от пользовательского crontab.
Стефан

@ Stéphane Chazelas Что касается синтаксиса теста, я предпочел его вместо [] или [[]], потому что сначала я попробовал свой скрипт на каком-то другом сервере, где я мог использовать crontab. После слишком многих сюрпризов с кронами у меня появилась привычка максимально использовать абсолютный путь в кронтабах. Кто-то может сказать, что это делает тесты уродливыми, и будет правильным ... но я отвечу, что тесты оболочки всегда в любом случае уродливы, и тоже будут правы простое копирование / вставка и включение некоторых пояснений.
Balmipour

1
Обратите внимание, что -aустарела в test. Как правило, вы будете использовать: hour=$(date +%H); if [ "$hour" -gt 2 ] && [ "$hour" -lt 7 ](или hour=`date +%H`если вам нужно быть совместимым с оболочкой Bourne, то есть Solaris 10 и старше, и, возможно, в настоящее время некоторые редкие подразделения SCO)
Стефан

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 = "$ (date +% 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.