Консольный будильник

Зохотелось мне, чтобы мой любимый пингвин будил меня по утрам. Порыскав по интернетам, нашёл, что нужно: скрипт, который будет плавно наращивать громкость песни и живым голосом (на основе festival) говорить мне, где я, кто я, сколько сейчас времени и градусов за окном. Чуть-чуть подработав под себя, получил следующее:

#!/bin/bash

# Используется синтезатор festival с поддержкой русской речи

# Инструкция по установке: http://habrahabr.ru/blogs/linux/60977/

# Данный скрипт срабатывает в заранее заданное время по cron'у. Затем он:

# 1) включает музыку на определенное время

# 2) Приветствует пользователя

# 3) Сообщает ему текущее время

# 4) Сообщает температуру за окном

# 5) Количество новых сообщений в Gmail'e

#

# Автор: h0rr0rr_drag0n

############################################################################

############################################################################

MUSIC_PLAYER=/usr/bin/mocp

play_music() {

$MUSIC_PLAYER -c

$MUSIC_PLAYER -s
$MUSIC_PLAYER -v -100

$MUSIC_PLAYER -v +10

$MUSIC_PLAYER -a ~/Музыка/Rammstein/2004\ -\ Reise,Reise\ [UICO-9006]\ [Japan]/11.\ Amour.mp3

$MUSIC_PLAYER -p

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 5

$MUSIC_PLAYER -v +5

sleep 2200

$MUSIC_PLAYER -s

}

play_music

# Склоняем в соответствующем падеже слова "минута" и "секунда"
CURR_HOUR=`date +%H | colrm 1 1`

CURR_MIN=`date +%M | colrm 1 1`

if [ "`date +%H`" -eq "11" ] || [ "`date +%H`" -eq "12" ] || [ "`date +%H`" -eq\ "13" ] || [ "`date +%H`" -eq "14" ]; then LC_HOUR="часов"

elif [ "$CURR_HOUR" -eq "0" ] || [ "$CURR_HOUR" -eq "5" ] || [ "$CURR_HOUR" \ -eq "6" ] || [ "$CURR_HOUR" -eq "7" ] || [ "$CURR_HOUR" -eq "8" ] || [ \ "$CURR_HOUR" -eq "9" ]; then LC_HOUR="часов"

elif [ "$CURR_HOUR" -eq "1" ]; then LC_HOUR="час"

elif [ "$CURR_HOUR" -eq "2" ] || [ "$CURR_HOUR" -eq "3" ] || [ "$CURR_HOUR" -eq \ "4" ]; then LC_HOUR="часа"

fi

if [ "`date +%M`" -eq "11" ] || [ "`date +%M`" -eq "12" ] || [ "`date +%M`" -eq \ "13" ] || [ "`date +%M`" -eq "14" ] || [ "$CURR_MIN" -eq "0" ] || [ "$CURR_MIN" \- eq "5" ] || [ "$CURR_MIN" -eq "6" ] || [ "$CURR_MIN" -eq "7" ] || [ "$CURR_MIN" \ -eq "8" ] || [ "$CURR_MIN" -eq "9" ]; then LC_MINUTE="минут"

elif [ "$CURR_MIN" -eq "1" ]; then LC_MINUTE="минута"

elif [ "$CURR_MIN" -eq "2" ] || [ "$CURR_MIN" -eq "3" ] || [ "$CURR_MIN" -eq "4" ]; then LC_MINUTE="минуты"

fi

# Получаем текущую дату\время

DATE_TIME=`date +%A\ %H\ $LC_HOUR\ %M\ $LC_MINUTE`

# Получаем температуру в Перми

CURR_TEMP="`wget -O - http://www.gismeteo.ru/city/daily/4079/ 2>/dev/null |\

grep '' | sed -r 's/(.[0-9]+).*/\1/g' | awk \
'{print $1}'`"

if [ "`echo $CURR_TEMP | sed -r 's/(.)[0-9]+/\1/g'`" == "+" ]; then

TEMP_SIGN="плюс"

else

TEMP_SIGN="минус"

fi

TEMP_DEGREE="`echo $CURR_TEMP | sed -r 's/.([0-9]+)/\1/g'`"

echo "С добрым утром. Сейчас $DATE_TIME. Температура за окном $TEMP_SIGN $TEMP_DEGREE градусов \

по Цельсию." | festival --tts --language russian

Итог: Музыка играет, слова говорятся. только вот при выполнении в консоли вылазит мерзкое
./alarm.sh: line 144: [: 23: ожидается использование унарного оператора
./alarm.sh: line 146: [: -eq: ожидается использование бинарного оператора
./alarm.sh: line 154: [: слишком много аргументов
./alarm.sh: line 154: [: -eq: ожидается использование бинарного оператора
./alarm.sh: line 176: {print $1}: команда не найдена

из за которого, как я предполагаю, не произносится температура. с шелл-скриптами знаком мало, поэтому откуда там берётся $1 и куда уходит - понять не в силах. пока что. Помогите, чем сможете!

Gim аватар

Первый косяк - в строчке
if [ "`date +%H`" -eq "11" ] || [ "`date +%H`" -eq "12" ] || [ "`date +%H`" -eq\ "13" ] || [ "`date +%H`" -eq "14" ]; then LC_HOUR="часов"

Там лишний бэкслэш после eq:

[ "`date +%H`" -eq\ "13" ]

Раньше он видимо экранировал перевод строки, но скорее всего после копирования начальное разбиение текста на строки поехало нафиг и появились такие артефакты. И этот кстати не единственный.

Ещё есть лишний пробел между "-" и "eq" в строчке:

if [ "`date +%M`" -eq "11" ] || [ "`date +%M`" -eq "12" ] || [ "`date +%M`" -eq \ "13" ] || [ "`date +%M`" -eq "14" ] || [ "$CURR_MIN" -eq "0" ] || [ "$CURR_MIN" \- eq "5" ] || [ "$CURR_MIN" -eq "6" ] || [ "$CURR_MIN" -eq "7" ] || [ "$CURR_MIN" \ -eq "8" ] || [ "$CURR_MIN" -eq "9" ]; then LC_MINUTE="минут"

Убрать пробел, удалить 6 артефактов и всё.

Правда фестиваль всё равно не читает, так в последней строке ему впихивают (по крайней мере у меня так):

С добрым утром. Сейчас Среда 01 час 21 минута. Температура за окном минус <!DOCTYPE <html><head> <title>GISMETEO.RU: <meta <link <link <!--[if  <div <div <SCRIPT adserver target random if document.write('<IFRAME document.write(' document.write('</IFRAME>'); // </SCRIPT> </div> <script var var var var var //размер function if( //Non-IE winWidth winHeight } //IE winWidth winHeight } //IE winWidth winHeight } //alert(winWidth); //alert(winHeight); } //положение function { var if obj } else obj } else obj } l t while { l t obj } //alert(l); //alert(t); } function getWindowSiz72890 getElementPositio72890 scrOfY0 scrOfX0 if( //Netscape scrOfY scrOfX } //DOM scrOfY scrOfX } //I6 scrOfY scrOfX } scrOfX scrOfY } // </body></html><!--www.gismeteo.r77 градусов cript.onreadystatechange if onload_inits();('AtlasFloater_Scrol72890 </script>
по Цельсию.

И он видимо давится.

Он явно давится. А вот так?..

# Получаем температуру в Перми

CURR_TEMP="`wget -O - http://www.gismeteo.ru/city/daily/4476/ 2>/dev/null |\

grep '' | sed -r 's/(.[0-9]+).*/\1/g' | awk \
'{print $1}'`"

# - после этого тэга как раз и идет температура в цифрах.

if [ "`echo $CURR_TEMP | sed -r 's/(.)[0-9]+/\1/g'`" == "+" ]; then

TEMP_SIGN="плюс"

else

TEMP_SIGN="минус"

fi

TEMP_DEGREE="`echo $CURR_TEMP | sed -r 's/.([0-9]+)/\1/g'`"

echo "С добрым утром. Сейчас $DATE_TIME. Температура за окном $TEMP_SIGN $TEMP_DEGREE градусов \

по Цельсию." | festival --tts --language russian

Потому что не верно с сайта вырезается температура.

С добрым утром. Сейчас Среда 01 час 51 минута. Температура за окном минус <!DOCTYPE <html><head> <tit <div <div <script adserver target random if document.write('<IFRAME document.write(' document.write('</IFRAME>'); // </script> </div> <script var var var var var //размер function if( //Non-IE winWidth winHeight } //IE winWidth winHeight } //IE winWidth winHeight } //alert(winWidth); //alert(winHeight); } //положение function { var if obj } else obj } else obj } l t while { l t obj } //alert(l); //alert(t); } function getWindowSiz72890 getElementPositio72890 scrOfY0 scrOfX0 if( //Netscape scrOfY scrOfX } //DOM scrOfY scrOfX } //I6 scrOfY scrOfX } scrOfX scrOfY } // // if(scrOfY+winHeight40 var if o </body></html><!--www.gismeteo.r77 градусов по Цельсию.dystatechange if onload_inits();>

Потому что в адресе "http://www.gismeteo.ru/city/daily/4476/ 2" пробел не нужен.

Вот полностью работающий скрипт.

Огромный спасибо. Подправил свой - стало ваапще идеально. Теперь мой пингвин будет меня будить)

Теперь возник вопрос, если расширить функционал... Допустим, в крон я его сейчас запихну. Можно ли его какие-то образом закольцевать, а-ля 10 start; 20 goto 10; 30 end; и убивать откуда-нить, типа /etc/init.d/alarm stop? то по выводу top видно только
24455 ezhario 20 0 360m 3504 1792 S 2.3 0.3 0:36.12 mocp , который и играет музыку?..

UPD убивать научился из консоли, killall alarm.sh && mcop -s
закольцевал, написав в начале скрипта while true; do
и дописав в конце done
Всё, готов будильник, который можно отключить, либо вырубив колонки (в моём случае - гитарный комбик), либо из консоли, что всё-таки заставит встать с кровати, тем самым проснуться.

Обрати внимание на слеши \
они означают что одна строка разбита на несколько, соответственно после них должен быть перевод строки.

Ну и в одном месте "- eq" лишний пробел, должно быть "-eq".

UPD: см. ответ Рейдана :) когда я писал, я ответа еще не видел

CORPSE аватар

Я думал над подобной вещью, только не по крону хотел, а используя команду at и через джаббер бота. Чтобы можно было написать что-нибудь вроде "Разбуди меня завтра в 6 утра металликой". Кстати, музыкальный центр будет включаться по питанию через одно хитрое устройство, управление которым будет реализовано через тот же скрипт. :)

Особо порадовал кусок:

 sleep 5

$MUSIC_PLAYER -v +5

Однако, уже давно изобрели циклы.

я пока что не знаю, как это делать.... чтобы оно всё само..

CORPSE аватар

Вот мой скрипт, которым я вытягиваю погоду через бота. Он выдаёт на три дня, но желающие могут ещё порезать.

 

#!/bin/bash

wget -q -O - http://www.nepogoda.ru/russia/perm/rss.xml | iconv -f CP1251 -t UTF-8 | grep -E '(<title>|<description>)' | tail -n 24 | cut -d ">" -f 2- | cut -d "<" -f 1 | sed 's/Пермь: /\n/g' | grep -v -E '(NEPOGODA|прогноз)'

Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Сохранить установки".