Is there a way that this script could display minutes instead of 1m ? Same with hours. Thanks.
#!/bin/bash # # Sound alarm after specifying time and message # Must input time delay AND message in double quotes !! # # # ** sleep can also accept intergers ex. sleep 7.63 # Made alias for it type al
Red='\e[0;31m' BRed='\e[1;31m' BIRed='\e[1;91m' # ${BIRed} this works Gre='\e[0;32m' BGre='\e[1;32m' BBlu='\e[1;34m' # ${BBlu} BWhi='\e[1;37m' Black='\e[0;30' BWhite='\e[0m 1;37' # This defines a variable containing the ANSI escape sequence to clear RCol='\e[0m';
soundfile="/usr/share/sounds/My_Sounds/Alarm_Clock_Sound.mp3" clear # amixer -D pulse sset Master 20% > /dev/null 2>&1 if [ -f "$soundfile" ]; then echo -e "${BGre}Soundfile is present." else echo "File $soundfile does NOT exist." echo echo "Program will now exit." exit fi
[ -z "$2" ] && { echo echo -e " ${BIRed}Error!! No time value given and/or message specified !!" echo echo -e " ${BBlu}Alarm Program 2018 ${RCol}" echo echo -e " alarm.sh [time value in seconds] Message in double Quotes"; echo -e " alarm 5m = 5 minute alarm" echo -e " alarm 5h = 5 hour alarm" echo -e " alarm 5d = 5 day alarm" echo -e " alarm 1.5m = 1 minute 30 seconds alarm" echo echo -e " alarm.sh 1m "\"Tea is ready."\""
echo exit 1; } echo -e "\033[30;5mTIMER COUNTING DOWN to $1 \033[0m" sleep $1 { for ((volume = 15; volume <= 70; volume += 2)); do # 2> /dev/null suppresses messages for amixer AND (c)vlc amixer -D pulse sset Master ${volume}% > /dev/null sleep .5s done } &
mpg123 $soundfile > /dev/null 2>&1
amixer -D pulse sset Master 70%
gxmessage -fg blue -font 'sans 20' -timeout 2 ' Tea is ready. !!' sleep 3s clear
Why is the script checking whether $2 is given as the "time value", when $1 is actually supposed to be the time value, and $2 is a "message"?
And to answer your original question - yes, it's possible to display e.g. "1 minute" instead of "1m", and e.g. "5 hours" instead of "5h" - just type in the first argument e.g. "5 hours" (exactly like this, in quotes) and convert this input to a value that sleep understands (before running the sleep command with defined time)
Converting this the other way round, e.g. for entered 5m to display as 5 minutes it would require some additional condition checks, but it should be possible as well.
In Bash, I tend to use printf over echo -e (they are both built-ins), and put the format in single quotes (which escape double quotes), and the args in double quotes (which escape single quotes). printf also has proper formatting and special character opportunities. Backslash is my least favourite character.
That could be generalized for all colors and attributes, and passing the attribute number is a bit ugly. There are various ways to change that (e.g. by defining one function per color and attribute or defining an assoc array), but this example is intended to be simple.
And instead of many single echos you can use Here Documents (see man bash):
Btw you only need -e for echoing strings that contain special escaped chars like \t (hor. tab) or \n (new line). printf does that by default, but it doesn't print a newline by default (like echo -n).
Quotes (generally) get stripped by the shell after it has used them to delimit strings, which is what you generally intend.
Backslashes are somewhat trickier. They are removed after they have done their job. But if a string is evaluated twice (perhaps entered once as a string and then used as a pattern), then you often need to escape the backslash with another backslash.
So you end up writing "\\n" (or possibly "\\\n") to get the string "\n" which then evaluates as a newline (and yes, I had to type five backslashes here in this post to get three visible ones).
I detest making the same error more than once in my life, so I only use backslash where it is bullet-proof. Typically, I might declare ASCII characters with ANSI-C Quoting (Bash Reference 3.1.2.4), like SOH=$'\001'; ESC=$'\033'; which is good for readability as well as syntax. Then I can expand those variables in shell, or pass them to awk with -v.
Of course, avoiding backslash means I won't ever get to be an expert with it.
I wrapped it in triple-backticks lines (makes a code block) for demo. Now without: \\\n
There is another icon at the top of the editor window, it looks like >_
While back-slashing and "escaping the escapes" are all valid alternatives, but they can get quite tedious to keep up - one would need to squint really hard to see what's happening....
One alternative I found useful (and it might not be related to the issue at hand) is bash's printf '%q' formatting. From man bash:
%b causes printf to expand backslash escape sequences in the corresponding argument in the same way as echo -e.
%q causes printf to output the corresponding argument in a format that can be reused as shell input.
%Q like %q, but applies any supplied precision to the argument before quoting it.
%(datefmt)T
causes printf to output the dateātime string resulting from using datefmt as a format string for strftime(3). The correspondā
ing argument is an integer representing the number of seconds since the epoch. Two special argument values may be used: -1
represents the current time, and -2 represents the time the shell was invoked. If no argument is specified, conversion behaves
as if -1 had been given. This is an exception to the usual printf behavior.
The %b, %q, and %T directives all use the field width and precision arguments from the format specification and write that many bytes
from (or use that wide a field for) the expanded argument, which usually contains more characters than the original.
another alternative is to use the "Inline No Parse" icon on the editor window that looks like a "crossed equal sign" and which expands to FOUR back-ticks.