📜 ⬆️ ⬇️

We write the console alarm clock on BASH-e

The task "Wake up in the morning" for me, frankly, is quite complicated. A week ago, I got the idea: to write a simple alarm clock that will play music louder and louder until you solve a mathematical example.




There are some articles and topics in Google, but this is not what is needed.
')
I’ll just say that the computer (in my case, the laptop) is in sleep mode at night, so it will need a little charge for the night (it takes about 30% of the battery overnight).
If you have a desktop computer, there are interruptions in electricity and there is no UPS , then do not risk.

Next, you need to make sure that your computer supports certain sleep modes. You can read about it here .

What do we need?

- rtcwake utility - for falling asleep computer (built into the kernel).
- Utility amixer - to gradually increase the volume of the sound.
- Any player that allows you to play music in a loop (in my case mplayer ).

Let's start

Set the necessary variables:
#    tm='07:05' #   volume=10 #   volume_max=90 #     sec=2 #    folder=~username/Music/alarm/* #     temp=`mktemp -t alarm_status_XXX.txt` 

Everything is clear here.
"Time to change the task" - idle time before generating a new task.
“Folder with music” - a folder from which you need to take a list of music. I just created the alarm folder and created hard links to the songs I need.
"Temporary file for status" - needed to complete the increase in volume. If there is a non-empty file, then we complete the background process (by the way, you can simply find our process through “jobs -l”).

Now you need to write a function that will kill the mplayer processes and / or re-play random music.
 #   alarm_start() { #    mplayer- jbs=(`ps al | grep [m]player | gawk -F ' ' '{print $3}'`) for job in ${jbs[*]} ; do kill -15 $jbs done #       if [ -z "$1" ] ; then mplayer -loop 0 -shuffle $folder &> /dev/null & fi } 

Also need to intercept signals the completion of the process.
 trap "echo -e '\n,  !' && sleep 1 && alarm_start" SIGINT SIGTERM SIGHUP SIGQUIT SIGTSTP SIGSTOP 

In order to be able to specify the waking time, we will use the optional parameter $ 1. Immediately do all the validity checks date.
 if [[ $# > 0 ]] ; then if [[ "$1" == [0-9]:[0-9][0-9] ]] || [[ "$1" == [0-9][0-9]:[0-9][0-9] ]] ; then tm=$1 else echo '  . : "07:00".' >&2 exit 10 fi fi date1=$(date -d "`date +%m/%d/%y` $tm" +%s) date2=$(date -d "`date +%m/%d/%y` $tm tomorrow" +%s) #   (  ) err=$? if [[ $err > 0 ]] ; then echo '  . : "07:00".' >&2 exit $err fi #       ,     if [[ $date1 < `date -u +%s` ]] ; then date=$date2 else date=$date1 fi 

The variables date1 and date2 are needed in case the user specifies the past date, then the time for waking up will be set tomorrow. If time is specified, for example, “07:99”, then the error code will be entered into the err variable.

Now you can "make" the computer to sleep. rtcwake requires superuser privileges . You can use sudo. Everything that you do - you do at your own peril and risk.
 #  sudo rtcwake -m mem -t $date #   amixer -q set Master $volume% #   alarm_start 

About rtcwake, as already mentioned, you can read here .

It remains only to make a volume increase and an example for the solution.
 #    while true ; do amixer sset Master 1%+ &> /dev/null volume=$(( $volume+1 )) if [ $volume -eq $volume_max ] ; then break elif [ -s "$temp" ] ; then rm "$temp" #    amixer -q set Master 50% break fi sleep 2 done & 

With the line “amixer sset Master 1% + &> / dev / null” we indicate that you need to increase the volume by 1 percent and do not need to display anything on the screen.
The ampersand & after the done operator is needed so that the volume increase is in the background.

And generate an example:
 clear echo '    :' while true ; do #  echo " $sec ." sleep $sec #     var1=$(( $RANDOM % 10000 - 5000 )) var2=$(( ($RANDOM % 100000 - 50000)/($RANDOM % 800 + 1) )) #  case $(( $RANDOM % 3 )) in 0) opt='+' result=$(( $var1 + $var2 )) ;; 1) opt='-' result=$(( $var1 - $var2 )) ;; 2) opt='*' var2=$(( ($RANDOM % 5 + 5) )) result=$(( $var1 * $var2 )) ;; esac #   if [[ $var2 < 0 ]] ; then if [[ "$opt" == '-' ]] ; then opt='+' var2=$(( $var2 * -1 )) elif [[ "$opt" == '+' ]] ; then opt='-' var2=$(( $var2 * -1 )) fi fi #  read -p "$var1 $opt $var2 = " answer #       if [[ $answer == $result ]] ; then echo "! : $result." break else clear echo -n "!   : $var1 $opt $var2 = $result." if [ -n "$answer" ] ; then echo "  : $answer." else echo "" fi fi done #   ,      alarm_start false #     echo "done" > "$temp" 


That's all. The alarm clock was written a week ago. The phone alarms were off. For this week I could easily wake up while solving an example (the problem can be very simple (1020 - 120) or difficult (394 * 5). One morning I came across an example of multiplication 13 times in a row).

You can create an alias in the ~ / .bashrc file: "alias alarm = '~ / path_to_script / alarm.sh'"
To prevent the alarm from turning off by closing the console program, I exit the current session and switch to another console (Alt + Ctrl + F1 or another F [1-7]).
If you wish, you can turn off the alarm by giving a forced close signal, but to do this you will need to go to another console, log in, find this process and kill. Faster probably solve an example :)

Full alarm code
 #!/bin/bash #  #   alarm_start() { #    mplayer- jbs=(`ps al | grep [m]player | gawk -F ' ' '{print $3}'`) for job in ${jbs[*]} ; do kill -15 $jbs done #       if [ -z "$1" ] ; then mplayer -loop 0 -shuffle $folder &> /dev/null & fi } #    tm='07:05' #   volume=10 #   volume_max=90 #     sec=2 #    folder=~username/Music/alarm/* #     temp=`mktemp -t alarm_status_XXX.txt` #      trap "echo -e '\n,  !' && sleep 1 && alarm_start" SIGINT SIGTERM SIGHUP SIGQUIT SIGTSTP SIGSTOP if [[ $# > 0 ]] ; then if [[ "$1" == [0-9]:[0-9][0-9] ]] || [[ "$1" == [0-9][0-9]:[0-9][0-9] ]] ; then tm=$1 else echo '  . : "07:00".' >&2 exit 10 fi fi date1=$(date -d "`date +%m/%d/%y` $tm" +%s) date2=$(date -d "`date +%m/%d/%y` $tm tomorrow" +%s) #   (  ) err=$? if [[ $err > 0 ]] ; then echo '  . : "07:00".' >&2 exit $err fi #       ,     if [[ $date1 < `date -u +%s` ]] ; then date=$date2 else date=$date1 fi #  sudo rtcwake -m mem -t $date # sudo echo "$date" > /sys/class/rtc/rtc0/wakealarm #   amixer -q set Master $volume% #   # day=$(( `date +%u` - 1 )) #   alarm_start #    while true ; do amixer sset Master 1%+ &> /dev/null volume=$(( $volume+1 )) if [ $volume -eq $volume_max ] ; then break elif [ -s "$temp" ] ; then rm "$temp" #    amixer -q set Master 50% break fi sleep 2 done & clear echo '    :' while true ; do #  echo " $sec ." sleep $sec #     var1=$(( $RANDOM % 10000 - 5000 )) var2=$(( ($RANDOM % 100000 - 50000)/($RANDOM % 800 + 1) )) #  case $(( $RANDOM % 3 )) in 0) opt='+' result=$(( $var1 + $var2 )) ;; 1) opt='-' result=$(( $var1 - $var2 )) ;; 2) opt='*' var2=$(( ($RANDOM % 5 + 5) )) result=$(( $var1 * $var2 )) ;; esac #   if [[ $var2 < 0 ]] ; then if [[ "$opt" == '-' ]] ; then opt='+' var2=$(( $var2 * -1 )) elif [[ "$opt" == '+' ]] ; then opt='-' var2=$(( $var2 * -1 )) fi fi #  read -p "$var1 $opt $var2 = " answer #       if [[ $answer == $result ]] ; then echo "! : $result." break else clear echo -n "!   : $var1 $opt $var2 = $result." if [ -n "$answer" ] ; then echo "  : $answer." else echo "" fi fi done alarm_start false #     echo "done" > "$temp" 


For convenience, the code is copied to pastebin so that you can download it .

I hope this alarm will make not sleep on study or work :)

Source: https://habr.com/ru/post/159987/


All Articles