Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I left the linux world for a few years and now i am trying to re-learn my shell scripting basics. I am writing a script for an alarm clock, but i seem to be running into a few issues. My script is posted below. If anyone could help, that would be great. Thanks.
------------------------------------------------------------
#!/bin/bash
declare -i H
declare -i M
declare -i currentH
declare -i currentM
declare -i minutesLeft
declare -i hoursLeft
echo -e "What Hour (24 Format) do you want to Wake Up?"
read H
echo -e "What Minute?"
read M
echo `expr $H + 0`
currentH=`date +%H`
currentM=`date +%M`
echo "You Selected "
echo "$H:$M"
echo -e "\nIt is Currently $currentH:$currentM"
if [ "$currentH" < "echo $H" ];
then
hoursLeft= `expr $H - $currentH`
echo "$H - $currentH means You Have: $hoursLeft hours still"
fi
if [ "$currentH" > "$H" ]; then
hoursLeft= `expr $currentH - $H`
echo -e "\n$currentH - $H means you have $hoursLeft hours left \n"
fi
if [ "$currentH" == "$H" ]; then
hoursLeft= 0
echo -e "Taking a nap?\n"
fi
if [ "$currentM" < "$M" ];
then
minutesLeft= `expr $M - $currentM`
echo -e "$M -$currentM menas you have: $minutesLeft minutes still"
fi
----------------------------------
My script, instead of doing what it should, produces the following errors:
./alarm: line 19: echo 11: No such file or directory
./alarm: line 26: 6: command not found
17 - 11 means you have hours left
./alarm: line 37: -41: command not found
11 -52 menas you have: minutes still
expr: non-integer argument
52 - 11 means you have 0 minutes left
Sleeping... for hours and 0 minutes
sleep: invalid time interval `h'
Try `sleep --help' for more information.
and if i choose the time 11:06, files called 11 and 6 are creating in the working directory. I am sure it is something really simple, but i haven't used linux or scripting on my computers in around 6 years. Thanks.
Yes the echo does not make sense. Sorry about that. That actually should have been cleaned up, but I deleted it from my script, but forgot to delete it from here.
Notice no quotations around the variable and the 3. When you use quotations, it should be for strings. -gt means "greater than", but there are other for less-than, equals, etc.. See bash man page for more on this.
2) When assigning values to vaiables, make sure there's no space after the "=" sign:
Code:
hoursLeft= `expr $H - $currentH`
^^
3) What does this do:
Code:
echo `expr $H + 0`
I mean, I know it supposed to echo something, but why? Just curious.... And for what it's worth, a bit less clunky way of doing simple math is like this, without expr:
Code:
echo $((VAR + 5))
echo $((VAR - OTHER_VAR))
Anyhow, check out that stuff and fix up your code a little. Then re-post the updated version for us in your next post. Please use code tags around your script ( see here: http://www.phpbb.com/community/faq.php?mode=bbcode#f2r1 )
If you're comparing whether the current hour value is less than the alarm hour, then the "echo " makes no sense.
Could you repost your code at http://pastebin.com/ (select Bash) so we can have line numbers, monospacing, and syntax highlighting?
I am trying to set an alarm. I am going to add a command to invoke mplayer at the given time after the sleep commands, but this is more than anything just me trying to get back into scripting. Kind of frustrating, because I used to be able to do kind of task fairly easily. Somehow I completely forgot almost everything.
Thanks AlucardZero and GrapefruiTgirl. Fixed it now. Runs well now. Here is the new code:
Code:
#!/bin/bash
declare -i H
declare -i M
declare -i currentH
declare -i currentM
declare -i minutesLeft
declare -i hoursLeft
echo -e "What Hour (24 Format) do you want to Wake Up?"
read H
echo -e "What Minute?"
read M
currentH=`date +%H`
currentM=`date +%M`
echo "You Selected "
echo "$H:$M"
echo -e "\nIt is Currently $currentH:$currentM"
if [ $currentH -lt $H ];
then
hoursLeft=`expr $H - $currentH`
echo "$H - $currentH means You Have: $hoursLeft hours still"
fi
if [ $currentH -gt $H ]; then
hoursLeft=`expr $currentH - $H`
echo -e "\n$currentH - $H means you have $hoursLeft hours left \n"
fi
if [ $currentH == $H ]; then
hoursLeft=0
echo -e "Taking a nap?\n"
fi
if [ $currentM -lt $M ];
then
minutesLeft=`expr $M - $currentM`
echo -e "$M -$currentM menas you have: $minutesLeft minutes still"
fi
if [ $currentM -gt $M ]; then
minutesLeft=`expr $currentM - $M`
echo -e "$currentM - $M means you have $minutesLeft minutes left \n"
fi
if [ $currentM == $M ]; then
minutesLeft=0
echo -e "and no minutes\n"
fi
echo -e "Sleeping... for $hoursLeft hours and $minutesLeft minutes \n"
sleep $hoursLeft\h
sleep $minutesLeft\m
mplayer ~/.alarm/alarm.mp3
Thanks everyone. Responses were quick and helpful.
Is it necessary for me to declare the variables as integers?
Not really, no. There must be a good reason that `declare` exists, (and actually I saw a recent example where it HAD to be used to define an array before using it) but I virtually never declare integers in any scripts I write. Doesn't seem to matter. The bash man page says:
Code:
A shell variable need not have its integer attribute turned on to be used in an expression.
So that's good for me. Someone else may have other thoughts on this...
However! I should add that, something to keep in mind is that: if you're doing integer comparisons with variables, and one or another variable that has not been given a value (or zero), but you expect it to have an integer (not a string) then you can get errors. Like so:
I had not set the variable $c to anything at all, so the error results. If I had set an integer value to $c there would be no error. Using `declare` beforehand, does not prevent this.
So i should set my integer variables equal to a non-zero number first? Thanks. The last code i posted doesn't work under all circumstances, but now that I have the very basics worked out, it shouldn't be too difficult. Thanks so much.
Well, take for example the following simple script:
Code:
#!/bin/bash
NAME="bob"
if [ "$NAME" = "fred" ]; then
c=5
fi
if [ $c -eq 5 ]; then
echo "c equals five"
fi
Logically, there's nothing wrong with the script. However, you see there's the possibility that the $c variable will not get set to 5 (or any other integer) and so in this case, if you run the script, it will fail with an error (unless you set NAME="fred" in the beginning).
To prevent the error, make sure $c will ALWAYS contain some integer, including zero, before comparing it. Tthere should either be an ELSE case to go with the IF test of the name, which sets c to some value other than 5; or, you should initialise c=0 at beginning of the script. So:
Code:
#!/bin/bash
NAME="bob"
if [ "$NAME" = "fred" ]; then
c=5
else
c=1
fi
if [ $c -eq 5 ]; then
echo "c equals five"
fi
Above, I added an ELSE, which sets $c to an integer; Now, $c ends up being an integer, regardless of what the $NAME was. No error is possible now, and we do not need to initialize c=0 in the start of the script.
Last edited by GrapefruiTgirl; 11-27-2010 at 06:10 PM.
Okay Thanks for all your help. After reading your replies I started over from scratch, and it works well now with no errors. Also, I added a countdown timer as well. Here is my new code. Try it out, and tell me what you think.
Code:
#!/bin/bash
#Script to set an alarm Clock, and use mplayer to wake up
#set alarm command
echo -e "Alarm Clock [a] or timer [t] (Case sensitive)?:"
read -N1 Choice
#if user Chose Alarm Clock
if [ $Choice == "a" ]; then
echo -e "\n"
setH=99
setM=99
currentH=99
currentM=99
hLeft=99
mLeft=99
echo -e "What Hour (24 Hour Format) Would you like to wake up?\n"
read setH
echo -e "What Minute?: "
read setM
#get current time
currentH=`date +%H`
currentM=`date +%M`
echo -e "\nYou Selected $setH:$setM.\n"
echo -e "It is currently $currentH:$currentM.\n"
#correct for entries such as 1:01 01:03, anything where first digit
#is a 0. There is probably an easier way, but I don't know it ;-)
#for setH
#--------------------------------------
if [ $setH == 00 ]; then
setH=0
fi
if [ $setH == 01 ]; then
setH=1
fi
if [ $setH == 02 ]; then
setH=2
fi
if [ $setH == 03 ]; then
setH=3
fi
if [ $setH == 04 ]; then
setH=4
fi
if [ $setH == 05 ]; then
setH=5
fi
if [ $setH == 06 ]; then
setH=6
fi
if [ $setH == 07 ]; then
setH=7
fi
if [ $setH == 08 ]; then
setH=8
fi
if [ $setH == 09 ]; then
setH=9
fi
#-----------------------------------------------
#for setM
#--------------------------------------
if [ $setM == 00 ]; then
setM=60
setH=$(($setH - 1))
fi
if [ $setM == 0 ]; then
setM=60
setH=$(($setH - 1))
fi
if [ $setM == 01 ]; then
setM=1
fi
if [ $setM == 02 ]; then
setM=2
fi
if [ $setM == 03 ]; then
setM=3
fi
if [ $setM == 04 ]; then
setM=4
fi
if [ $setM == 05 ]; then
setM=5
fi
if [ $setM == 06 ]; then
setM=6
fi
if [ $setM == 07 ]; then
setM=7
fi
if [ $setM == 08 ]; then
setM=8
fi
if [ $setM == 09 ]; then
setM=9
fi
#-----------------------------------------------
#for CurrentH
#--------------------------------------
if [ $currentH == 00 ]; then
currentH=0
fi
if [ $currentH == 01 ]; then
currentH=1
fi
if [ $currentH == 02 ]; then
currentH=2
fi
if [ $currentH == 03 ]; then
currentH=3
fi
if [ $currentH == 04 ]; then
currentH=4
fi
if [ $currentH == 05 ]; then
currentH=5
fi
if [ $currentH == 06 ]; then
currentH=6
fi
if [ $currentH == 07 ]; then
currentH=7
fi
if [ $currentH == 08 ]; then
currentH=8
fi
if [ $currentH == 09 ]; then
currentH=9
fi
#-----------------------------------------------
#for currentM
#--------------------------------------
if [ $currentM == 00 ]; then
currentM=0
fi
if [ $currentM == 01 ]; then
currentM=1
fi
if [ $currentM == 02 ]; then
currentM=2
fi
if [ $currentM == 03 ]; then
currentM=3
fi
if [ $currentM == 04 ]; then
currentM=4
fi
if [ $currentM == 05 ]; then
currentM=5
fi
if [ $currentM == 06 ]; then
currentM=6
fi
if [ $currentM == 07 ]; then
currentM=7
fi
if [ $currentM == 08 ]; then
currentM=8
fi
if [ $currentM == 09 ]; then
currentM=9
fi
#-----------------------------------------------
#I realize that was pretty redundant. Does anyone Know a better way?
#correct for a period of 24 hours
if [ $setH == $currentH ]; then
if [ $setM -le $currentM ]; then
setH=$(( $setH + 24))
echo -e "Quite a long Nap You're Taking... About 1 Day\n"
fi
fi
#If the Current Hour is less than the set hour
#subtract for hours remaining
if [ $currentH -lt $setH ]; then
hLeft=$(($setH - $currentH))
#if current Hour is greater than set Hour
else if [ $setH -lt $currentH ]; then
hLeftA=$(($currentH - $setH))
hLeft=$((24 - $hLeftA))
#if equal
else
hLeft=0
echo -e "\nShort nap. $hLeft hours"
fi
fi
#Make script output hours set; use correct plurality of "hour" or "hours"
if [ $hLeft == 1 ]; then
echo "You have $hLeft hour"
else if [ $hLeft -gt 1 ]; then
echo "You have $hLeft hours"
fi
fi
#Do the Same as Above, but for the Minutes
#subtract for minutes remaining
if [ $currentM -lt $setM ]; then
mLeft=$(($setM - $currentM))
#if current Hour is greater than set Hour
else if [ $setM -lt $currentM ]; then
mLeft=$(($currentM - $setM))
#if equal
else
mLeft=0
echo " and no minutes"
fi
fi
#make script output minutes set, with correct plurality of "minute or "minutes"
if [ $mLeft == 1 ]; then
echo " and $mLeft Minute\n"
else if [ $mLeft -gt 1 ]; then
echo " and $mLeft Minutes"
fi
fi
# Subtract 1 Hour if more than 0 minutes (since part of the hour is taken by the minutes)
if [ $mLeft -gt 0 ]; then
hleft=$(($hleft -1))
fi
#invoke sleep
if [ $mLeft -gt 0 ]; then
echo -e "\nSleeping for: $hLeft hours and $mLeft minutes"
fi
if [ $mLeft == 0 ]; then
echo -e "\nSleeping for: $hLeft hours."
fi
sleep $hLeft\h
echo -e "\nNow 0 hours and $mLeft minutes\n"
sleep $mLeft\m
echo -e "DONE\n"
#run alarm Command
mplayer ~/alarm.mp3
exit 0
fi
#if user chose Timer
if [ $Choice == "t" ]; then
echo -e "\n"
H=99
M=99
echo -e "How many Hours: "
read H
echo -e "\nHow many Minutes: "
read M
echo -e "You Chose $H hours and $M minutes."
echo -e "Setting Timer For $H:$M"
sleep $H\h
sleep $M\m
echo -e "\nDONE\n"
#run alarm command
mplayer ~/alarm.mp3
exit 0
fi
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.