определение дня недели в цикле и запуск функции

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Ответить
Аватара пользователя
nerve
Сообщения: 280
ОС: OpenBSD

определение дня недели в цикле и запуск функции

Сообщение nerve »

скрипт находится в /etc/cron.daily
function1 отрабатывает как и положено по понедельникам.
function2 должна отрабатывать все дни кроме воскресенья и понедельника, но в воскр и понед она все равно отрабатывается.

Код: Выделить всё

#!/bin/bash

CURDAY=`date +"%A"`
MOND=Monday
SUN=Sunday

function1 () {
code here
}

function2 () {
code here
}

[[ $CURDAY = $MOND ]] && function1 && exit 0
if [ $CURDAY != $MOND -o $CURDAY != $SUN ];
  then
     function2
fi
exit 0
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: определение дня недели в цикле и запуск функции

Сообщение /dev/random »

Вам нужно -a, а не -o в условии.

Да, и хоть к указанной проблеме это не относится, но всё же: я бы порекомендовал %u (номер дня недели), а не %A (название), поскольку команда может выдать локализованное название вместо английского.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: определение дня недели в цикле и запуск функции

Сообщение Bizdelnick »

Во-первых, вместо date +%A вызывайте date +%u, чтобы вывод не зависел от локали, и сравнивайте с 1 и 7.
Во-вторых, что-то Вы напутали: если function1 по понедельникам выполняется успешно,то скрипт должен завершиться и function2 не выполнится.
В-третьих, проверка в if всегда завершится успешно; чтобы она работала как задумано, надо вместо -o поставить -a.
В-четвёртых, почему просто не написать два отдельных скрипта и не прописать их в crontab на нужные дни?

Upd. /dev/random меня опередил. :-)
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
nerve
Сообщения: 280
ОС: OpenBSD

Re: определение дня недели в цикле и запуск функции

Сообщение nerve »

Парни, спасибо за ответ, правильно ли я понял что надо привести к такому виду оба условия:

Код: Выделить всё

[[ $CURDAY = $MOND ]] && function1
if [ $CURDAY != $MOND -a $CURDAY != $SUN ];
  then
     function2
fi
exit 0

с разными файлами в кронтабе было бы проше, а тут как раз возможность поэксперементировать с условием.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: определение дня недели в цикле и запуск функции

Сообщение Bizdelnick »

Да, такой вариант должен работать.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: определение дня недели в цикле и запуск функции

Сообщение drBatty »

Bizdelnick писал(а):
06.10.2013 16:38
В-четвёртых, почему просто не написать два отдельных скрипта и не прописать их в crontab на нужные дни?

плюсую этот вариант. Не нужно плодить лишние сущности.
nerve писал(а):
06.10.2013 16:49
if [ $CURDAY != $MOND -a $CURDAY != $SUN ];

лично я предпочитаю ленивый вариант с двумя [. Т.е.

Код: Выделить всё

if [ $CURDAY != $MOND ] && [ $CURDAY != $SUN ]; then


PS: да, у вас лишняя точка с запятой после ].
nerve писал(а):
06.10.2013 16:23
[[ $CURDAY = $MOND ]] && function1 && exit 0

а здесь башизм почему-то. И да, exit 0 не нужно. Нужно просто exit.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
nerve
Сообщения: 280
ОС: OpenBSD

Re: определение дня недели в цикле и запуск функции

Сообщение nerve »

спасибо.
то есть, если then в той же строке, что и условие с if-ом, тогда после условия должна стоять точка с запятой.
а если then в новой строке то ; не нужна?
ленивый вариант по сути ведь тоже самое?
я прочитал, что в условиях переменные обязательно надо брать в двойные кавычки. или это устаревшее требование?
update: хорошо что я не привел сами функции, там бы просто порвали на части за всякие ошибки)
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: определение дня недели в цикле и запуск функции

Сообщение /dev/random »

nerve писал(а):
07.10.2013 21:17
я прочитал, что в условиях переменные обязательно надо брать в двойные кавычки. или это устаревшее требование?

В [ ] обязательно (иначе будут проблемы, если в переменной окажется пробел), в [[ ]] - нет.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: определение дня недели в цикле и запуск функции

Сообщение drBatty »

nerve писал(а):
07.10.2013 21:17
то есть, если then в той же строке, что и условие с if-ом, тогда после условия должна стоять точка с запятой.

именно так. Точка с запятой нужна тогда и только тогда, когда у вас ДВА оператора в одной строке.

Код: Выделить всё

if УСЛОВИЕ

это один оператор

Код: Выделить всё

then ДЕЙСТВИЕ

второй оператор

ДЕЙСТВИЕ можно делать и в другой строке. Вот так:

Код: Выделить всё

if УСЛОВИЕ
then
  ДЕЙСТВИЕ
fi


синтаксически верно и так

Код: Выделить всё

if УСЛОВИЕ
then ДЕЙСТВИЕ
fi

Код: Выделить всё

if УСЛОВИЕ; then ДЕЙСТВИЕ
fi

Код: Выделить всё

if УСЛОВИЕ; then ДЕЙСТВИЕ;fi


тк, как вы написали -- тоже можно. Но не нужно.

И да, ДЕЙСТВИЕ должно быть. Иначе пишите так:

Код: Выделить всё

if УСЛОВИЕ; then
  :
else
  ДЕЙСТВИЕ2
fi

двоеточие == пустой оператор, который ничего не делает.
nerve писал(а):
07.10.2013 21:17
ленивый вариант по сути ведь тоже самое?

а это сложный вопрос. На самом деле, [ это КОМАНДА, и в man test про это не написано. А написано, что команда может быть заменена оболочкой. В man bash тоже про это не написано. Потому -- я не знаю, как оно получится у вас. А значит, такой быдлокод лучше не писать. Впрочем -- может здешние гуру внесут ясность в этот вопрос...

nerve писал(а):
07.10.2013 21:17
я прочитал, что в условиях переменные обязательно надо брать в двойные кавычки. или это устаревшее требование?

синтаксис не устаревает. Лучше всего брать в одиночные, но тогда нельзя юзать переменные. Если нужны переменные, то лучше двойные, ибо иначе может получится ПУСТО. Синтаксис не терпит пустоты. Т.е. есть синтаксическая разница между ПУСТО и "".

$

$ sh x.sh \x.sh: line 2: [: ==: ожидается использование унарного оператора $ cat x.sh EMPTY= if [ $EMPTY == "" ]; then echo "EMPTY" fi


Но двойные кавычки исправят ситуацию.

nerve писал(а):
07.10.2013 21:17
хорошо что я не привел сами функции, там бы просто порвали на части за всякие ошибки

модераторы-бы потёрли тонны мата. (:

PS:
drBatty писал(а):
08.10.2013 12:20
\x.sh: line 2: [: ==: ожидается использование унарного оператора

в данном случае, команда [ ждёт, что я напишу что-то типа

Код: Выделить всё

[ -f filename ]

т.е. унарный оператор -f проверит, является-ли filename регулярным файлом?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: определение дня недели в цикле и запуск функции

Сообщение Bizdelnick »

drBatty писал(а):
08.10.2013 12:20
На самом деле, [ это КОМАНДА, и в man test про это не написано. А написано, что команда может быть заменена оболочкой. В man bash тоже про это не написано.

И в man test, и в man bash-builtins команда [ описана довольно подробно. В первом случае - как альтернативный способ вызова test, во втором - ещё и в разделе о встроенных командах bash. ИМХО вполне очевидно, что речь идёт именно о команде, а не о ненужной закорючке.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: определение дня недели в цикле и запуск функции

Сообщение drBatty »

Bizdelnick писал(а):
08.10.2013 12:29
ИМХО вполне очевидно, что речь идёт именно о команде, а не о ненужной закорючке.

лучше скажите, где написана ленивость оператора -a внутри скобок?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: определение дня недели в цикле и запуск функции

Сообщение Bizdelnick »

Вы о чём?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: определение дня недели в цикле и запуск функции

Сообщение drBatty »

Bizdelnick
ну ТС интересовался: "это одно и то же?". Я не знаю. Является-ли -a в скобках ленивым? Да/Нет?

PS: Метод тыка не принимается, дайте цитату из документации.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: определение дня недели в цикле и запуск функции

Сообщение Bizdelnick »

Вы о приоритетах или о чём? Я термина "ленивый оператор" не знаю.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: определение дня недели в цикле и запуск функции

Сообщение drBatty »

Bizdelnick писал(а):
08.10.2013 13:34
Я термина "ленивый оператор" не знаю.

ну вот например

очевидно, если X ложное, то и конъюнкция тоже ложная, и Y можно не вычислять. В некоторых ЯП и не вычисляется, причём это задокументированно в стандарте (например для C/C++). AFAIK для BASH поведение && такое же. А вот для -a -- не знаю. Не задумывался. Потому-то и избегаю применять такие операторы.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: определение дня недели в цикле и запуск функции

Сообщение /dev/random »

drBatty писал(а):
08.10.2013 13:43
А вот для -a -- не знаю. Не задумывался.

А что тут можно не знать? [ - команда. Встроенная или внешняя, но команда, а не специальная синтаксическая конструкция вроде [[. Никаких ленивых вычислений у её аргументов быть не может в принципе. Если команда запустилась, значит, все её аргументы вычислены.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: определение дня недели в цикле и запуск функции

Сообщение drBatty »

/dev/random писал(а):
08.10.2013 14:02
Если команда запустилась, значит, все её аргументы вычислены.

ну значит -- плохо. Да, в bash считает...


nerve писал(а):
07.10.2013 21:17
ленивый вариант по сути ведь тоже самое?

нет

вариант

Код: Выделить всё

[ 1 != 1 ] && [ $(mktemp) ]

НЕ создаёт временный файл

Вариант

Код: Выделить всё

[ 1 != 1 -a $(mktemp) ]

Создаёт временный файл.

Но результат обоих команд всегда ложь.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20793
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: определение дня недели в цикле и запуск функции

Сообщение Bizdelnick »

drBatty писал(а):
08.10.2013 14:19
Вариант

Код: Выделить всё

[ 1 != 1 -a $(mktemp) ]

Создаёт временный файл.

Логично. Выражение $(mktemp) вычисляется до запуска [.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: определение дня недели в цикле и запуск функции

Сообщение drBatty »

Bizdelnick писал(а):
08.10.2013 15:55
Логично. Выражение $(mktemp) вычисляется до запуска [.

тут нет "запуска [", у меня bash, и он не использует /bin/[. Могла-бы и не запускать. Но -- запускает.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: определение дня недели в цикле и запуск функции

Сообщение /dev/random »

drBatty писал(а):
08.10.2013 20:24
тут нет "запуска [", у меня bash, и он не использует /bin/[. Могла-бы и не запускать. Но -- запускает.

Тут нет запуска /bin/[, но запуск [ (как встроенной команды, выполняющейся в рамках того же процесса, но всё же команды, а не языковой конструкции) есть.
Спасибо сказали:
Аватара пользователя
nerve
Сообщения: 280
ОС: OpenBSD

Re: определение дня недели в цикле и запуск функции

Сообщение nerve »

сильно не пинайте, вот сам скрипт. опыта почти нет, так что главное было получить результат.
join.awk был сделан человеком вот здесь: http://www.linux.org.ru/forum/general/9633085
я в нем так до конца и не разобрался.

Код: Выделить всё

#!/bin/bash
#
#one more example to detect previous week
#WHERE WEEK (time_entries.spent_on) = WEEK( CURRENT_DATE ) - 1  AND YEAR( time_entries.spent_on ) = YEAR( current_date )
#
DATE=`date --date="1 day ago" +%A,\ %d/%m/%Y`
CURDAY=`date +"%A"`
MOND=Monday
SUN=Sunday
spentdaily () {
cd /root
rm -rf ./spentfull.2 ./spentfull.7
#echo "<html>" > spentfull.1
#echo "<head>" >> spentfull.1
#echo "<meta content=\"text/html; charset=ISO-8859-1\"" >> spentfull.1
#echo "http-equiv=\"Content-Type\">" >> spentfull.1
#echo "</head>" >> spentfull.1
#echo "<body bgcolor="#FFFFFF" text="#000000">" >> spentfull.1
#echo "<table border="1">" >> spentfull.1
#echo "<tr><td>Login(total)</td><td>Project name</td><td>Link to issue</a></td><td>Spent hours</td></tr>" >> spentfull.1
#mysql --batch --raw -u root -ppass -e  "use db; \
mysql -u root -ppass -e  "use db; \
SELECT users.login, projects.name, time_entries.issue_id, time_entries.hours \
FROM users, time_entries INNER JOIN projects \
ON time_entries.project_id = projects.id \
WHERE time_entries.spent_on = SUBDATE(CURDATE(),1) \
AND time_entries.user_id = users.id \
ORDER BY users.login;" | while IFS=$'\t' read login project issue hours; do
echo "<tr><td>$login</td><td>$project</td><td>$issue</td><td>$hours" >> spentfull.2
done
#sort spentfull.4 > spentfull.5
#echo "</body>" >> spentfull.3
#echo "</html>" >> spentfull.3
sed '1d' spentfull.2 | \
awk 'BEGIN { FS = "</td><td>" ; OFS = "</td><td>" } tot+=$4 {if($3 !~ /NULL/) $3="<a href=\"https://redmine.org/issues/"$3"\">"$3"</a>"}  {print $0} END { print "The team spent " tot " hours yesterday." }' | \
sed -e 's/$/<\/td><\/tr>/' -e '$s/<\/td><\/tr>//' > spentfull.7

mysql -u root -ppass -e " use db; \
SELECT users.login, SUM(ROUND(time_entries.hours, 2)) \
FROM users, time_entries \
WHERE time_entries.spent_on = SUBDATE(CURDATE(),1) \
AND time_entries.user_id = users.id \
GROUP BY users.login;" | while IFS=$'\t' read login1 hours2; do
echo "<tr><td>$login1</td><td>$hours2" >> spentfull.8
done
sed '1d' spentfull.8 > spentfull.9
./join.awk spentfull.9 spentfull.7 > spentfull.10
sed -e '$s/()//' -e '$s/^/<\/table>/' spentfull.10 > spentfull.12
#comm -3 --nocheck-order --output-delimiter='</td><td>' spentfull.6 spentfull.8 > spentfull.9
#awk -F"\t" 'BEGIN { printf "%s\t %-75s %-60s %s\n", "User", "Project name", "Link to issue", "Time<br>" } \
#{if($3 !~ /NULL/) $3="<a href=\"https://redmine.org/issues/"$3"\">"$3"</a>"} \
#{printf "%s\t %-75s %-60s %s\n", $1, $2, $3, $4}' spentfull.5 > spentfull.6
cat spentfull.1 spentfull.12 spentfull.3 > spentfull.html
mutt -e 'set content_type="text/html"' -s "Spent time report for $DATE" -- users@domain.com < /root/spentfull.html
}
spentweekly () {
cd /root
rm -rf ./spentweek.2
#echo "<html>" > spentweek.1
#echo "<head>" >> spentweek.1
#echo "<meta content=\"text/html; charset=ISO-8859-1\"" >> spentweek.1
#echo "http-equiv=\"Content-Type\">" >> spentweek.1
#echo "</head>" >> spentweek.1
#echo "<body bgcolor="#FFFFFF" text="#000000">" >> spentweek.1
#echo "<table border=\"1\">" >> spentweek.1
#echo "<tr><td>Login</td><td>Weekly spent hours</td></tr>" >> spentweek.1
mysql -u root -ppass -e  "use db; \
SELECT users.login, SUM(ROUND(time_entries.hours, 2)) AS expr1 \
FROM time_entries, users WHERE time_entries.spent_on >= DATE(NOW()) - INTERVAL 7 DAY \
AND time_entries.spent_on < CURDATE() AND time_entries.user_id = users.id \
GROUP BY users.login;" | while IFS=$'\t' read login3 hours3; do
echo "<tr><td>$login3</td><td>$hours3</td></tr>" >> spentweek.2
done
sed 1d spentweek.2 > spentweek.3
mysql -u root -ppass -e  "use db; \
SELECT SUM(ROUND(time_entries.hours, 2)) \
FROM time_entries, users WHERE time_entries.spent_on >= DATE(NOW()) - INTERVAL 7 DAY \
AND time_entries.spent_on < CURDATE() AND time_entries.user_id = users.id;" > spentweek.5
sed -e 1d -e 's/^/Last week team spent hours is /' -e '$s/^/<\/table>/' spentweek.5 > spentweek.8
#echo "</body>" > spentweek.4
#echo "</html>" >> spentweek.4
cat spentweek.1 spentweek.3 spentweek.8 spentweek.4 > spentweek.html
mutt -e 'set content_type="text/html"' -s "Spent time report for last week" -- users@domain.com < /root/spentweek.html
}
[[ $CURDAY = $MOND ]] && spentweekly
if [ $CURDAY != $MOND -a $CURDAY != $SUN ]
  then
     spentdaily
fi
exit 0
Спасибо сказали:
Ответить