As part of learning Bash, I wrote a little sleep timer to emulate those found on TV's. The script has taken many forms, and has gained some additionally functionality. The initial post here was getting quite messy so I've simplified it to reference only the most recent script. This is the cleanest looking version, the easiest to sub-in your own commands to fit with the actions you'd like to take after the sleep timer.
By default the script depends on: bc (a command line calculator program), pm-utils (for suspend/hibernate), cvlc (command line vlc), & xscreensaver. The last three can be replaced with substitutes, by editing the relevant functions at the beginning of the script.
What the script does:
In it's simplest form it simply outputs a countdown from a defined number of minutes, and then takes a specified action. By default the following actions are included: suspend, hibernate, lock, poweroff, alarm. (To add another action simply add a function at the top, and a command line flag for it.) For example, to suspend after 40 minutes:
bashtimer.sh -s -m 40
There is also a more complex routine called "wait" which will either run a script, or watch an already running process (via its PID number) and wait for it to complete before taking an action. If no time is specified it will take the action right away, if a time is specified (say 40 minutes) it will take the action either when the passed PID/script completes, or after 40 minutes--whichever is later. For example, to suspend after running a backup script, but not an earlier than 30 minutes:
bashtimer.sh -s -w ~/bin/backup.sh -m 30
If "-w PID/script" is not specified, it will default to the normal timer mode.
If no action or time is specified it will prompt for input. Where necessary it will also prompt for a users sudo password. (Note, you can go sudo-free by switching to the dmesg commands commented out in the suspend & hibernate function and then commenting out the password-prompting bit. ) Before using the alarm, you'll want to specify the path to the sound file you'd like to play (Line 39).
The most recent version of the script can be found at: http://crunchbanglinux.org/pastebin/926
Feel free to post comments / feature requests etc. I'm still very much a newcomer to all this. Thanks to those below who have already provided very helpful feedback.
Last edited by jmbarnes (2011-01-27 21:04:15)
I just wanted to thank you for posting this, it's awesome. I've hacked around with using the program gshutdown using gksu and putting a custom command in for pm-hibernate and pm-suspend. But I've never gotten it to work that great.
Your script is nice, thanks for putting it up - works well.
Last edited by tshann (2010-03-07 20:33:26)
Glad it could help. I haven't played with gshutdown--but I don't see any reason for a whole gui etc when terminal does what I need. Let me know if you have any thoughts, or ideas on how to implement password-check or countdown. (Very much a new bash scripter with no formal training.)
Your script is MUCH preferrable to hacking gshutdown. Eventually, I'd like to edit it to allow a choice for the user to pick pm-hibernate OR pm-suspend. A relatively easy edit I believe.
As for a password-check and countdown, not sure. I'm not a programmer at all. From your script you are clearly more advanced than I. Having said that, I know in DOS they have some kind of string test. But I suspect there is an error message that comes up, or code. So you'd have to set your script to gather all the information needed, then try to implement it. If the user typed in the wrong password, it'd generate an error code, the script would catch that and come back with a dialogue " wrong password, please try again."
I'm sure you know all this, I just don't know how to implement it. I suspect that's what you're looking for help with.
Another idea I had, if I had the time, is to utilize either zenity and or gxmessage http://www.linuxjournal.com/content/tec … ges-scipts to have the dialogues come up in a gui. I believe that zenity has a progress bar in it and you might be able to set it to correlate with the time going by, but don't know how that is done.
Ultimately, it'd be great to set this up to connect to a shortcut key. You press the shortcut key, say W-s, a dialogue would come up with an option asking for password and whether you want to hibernate or suspend, and for how long. Then you set it, and bing a little progress comes up, or a notification in the satus bar counts it down for you. Consider this little utility: http://www.linuxjournal.com/content/tec … otify-send. I think it'd be better to have it script based WITH dialogues because it'd be nicer to set up as a shortcut key than a strictly terminal based script - I THINK. Also the two above programs don't take up much resources and I believe they both can be used in the same script as well.
Well, those are my thoughts. I'm kind of zapped for time, so can't contribute much more than some ideas. Once things calm down, I could spend the hours and hours it'd take me to google all the above and debug the script. But for now, I'm just grateful for what you'd done so far. It's awesome. If I make the minor change to add the pm-hibernate choice @ some point, I'll post it.
Thanks for the leads. Seems like either wouldn't be too hard to implement--though I've never done either. I was thinking about learning a bit of python over my next break and writing it up in that (so it would be similar to oblogout etc that comes with #!.) Have no idea how tough that would be, but no doubt would be a good learning experience.
Hibernate is now a choice (sometimes sitting in class as a TA has its advantages ). I've also added a 5 minutes-to-suspend notification via notify-send (though you will have install the quite small package.)
I bind it to the shortcut via the standard openbox method (just change the Path and key combo):
<keybind key="XF86Mail"> <action name="Execute"> <execute>terminator --command="~/bin/sleeptest.sh"</execute> </action> </keybind>
Last edited by jmbarnes (2010-03-09 01:16:38)
Great work! Looks good, I'll grab your current updated script and try it out. I'm happy just with the script myself.
But if you can put this into py, that'd be awesome. But then you'd be rising up out of the category of "terminal Hack" up into the upper stratosphere of programming
I currently use some of adcomps awesome python scripts and find them really sweet. Oblogout is also dynamite. Keep up the good work.
EDIT: Now with alarm (plays music via vlc)
EDIT(2): Edited to be prettier, and make sure modules don't suspend with alarm.
EDIT(3): Alarm works more 'as expected' (and repeats until dismissal.)
Had a few hours this morning to mess around. I've come up with a GUI version that is a shell script that calls out zenity. The benefit of zenity is that is seems to be installed by default on #!--so their is nothing extra to add in.
The gui includes two countdown progress bars, one for the length of time, and one for the last 60 seconds. Pressing "cancel" will abort the sleep timer.
This can easily be attached to a keybinding or placed in the menu. In addition its quite a minimal task to tie it directly into the logout script supplied by corenomial (the one in the default menu.) If anyone is interested in this version of the logout script let me know and I'll drop it in pastebin.
#!/bin/bash ##This is a script that acts a a sleep timer or basic alarm. ##It relies on zenity, pm-utilities, and vlc. It will run on a default ##crunchbang installation. ## ##Things you might want to edit include: ##Things to do before / after suspend (remove / add modules) ##The pm-suspend/hibernate command (other suspend commands should work here.) ##Default alarm ##Edit path to set your default alarm (i.e. a music file) ##uncomment next line for #! default noise=/usr/share/gdm/themes/CrunchBang/crunchbang.wav #########The inputs########## ##action after timer offwith=$(zenity --list --text "Please select action after timer:" --radiolist --column "Pick" --column "Sleep by" TRUE pm-suspend FALSE pm-hibernate FALSE play-alarm FALSE cancel); if [ $? = 1 ]; then exit fi if [ "$offwith" = "cancel" ]; then exit fi if [ "$offwith" = "play-alarm" ]; then zenity --question --text="Default alarm or choose your own?" --ok-label="Default" --cancel-label="Choose..." if [ $? = 1 ]; then cd ~/music noise=$(zenity --file-selection); if [ $? = 1 ]; then zenity --warning --title="Sleep Timer" --text="Default alarm will be used." fi fi fi ##timer length minutes=$(zenity --entry --title="Sleep Timer" --text="How long of a delay (in minutes)?"); if [ $? = 1 ]; then exit fi ##sudo password pass=$(zenity --entry --title="Sleep Timer" --text="Please enter sudo password:"); if [ $? = 1 ]; then exit fi #######Calculating time off###### sectime=`date +%s` secoff=$(($sectime+($minutes*60))) dateoff=`date --date=@$secoff` #########The Timer bits########## #A little while-loop to get percentages of time passed. #Percentages are passed to a progress bar. #The main timer. elapsedtime=1 ( while [ $elapsedtime -lt $minutes ] do sleep 1m echo "$(echo "scale=4; ($elapsedtime/$minutes)*100" | bc)" elapsedtime=$(($elapsedtime+1)) done ) | zenity --progress --auto-kill --auto-close --title="Sleep Timer" --text="Will $offwith on $dateoff. Press cancel to abort." #The last 60 seconds.... lastsixty=1 ( while [ $lastsixty -le 60 ] do sleep 1s echo "$(echo "scale=4; ($lastsixty/60)*100" | bc)" lastsixty=$(($lastsixty+1)) done ) | zenity --progress --auto-kill --auto-close --title="Sleep Timer" --text="Will $offwith in 60 seconds. Last chance to cancel." ########The Action Bits############ ##Notice some banshee commands commented out. Some set of ##commands like these (or if you use banshee, these) are useful if ##you listen to music and want an alarm that stops it and play the alarm. if [ "$offwith" = "play-alarm" ]; then cvlc --repeat "$noise" & zenity --info --title="Sleep Timer" --text="Time to awake, or take a break. Press 'ok' to dismiss the alarm."; vlcpid=$! #banshee --stop #banshee --play-enqueued "$noise" & zenity --info --title="Sleep Timer" --text="Time to awake, or take a break. Press 'ok' to dismiss the alarm."; if [ $? = 0 ]; then kill $vlcpid #banshee --stop exit 0 fi fi #Unload modules before suspending. echo "$pass" | sudo -S modprobe -r airo #The actual suspend/hibernate command. #NOTE: it passes the literal string from the first menu. If you need a #different suspend command you must echo "$pass" | sudo -S $offwith --auto-quirks #Things to do on wakeup. echo "$pass" | sudo -S modprobe airo exit #end
Last edited by jmbarnes (2010-03-25 18:31:17)
JM - AWEsome work!
Yeah! I can't wait to give this a spin, to tweak it a bit for my purposes. But thanks for building this. I've been thinking about tweaking it a bit to do other things - but now I can't remember what they were!
but again, thanks for sharing, I'm very excited about this.
I just remembered. I've been wanting a simple alarm for my Crunchbox - this is it. Even though I'm not a programmer, It appears it wouldn't be that difficult to alter a few things to have it delay for a time, and then run a song (que and play a tune in rhythmbox for example). Thanks again for this awesome program.
Nice idear on the alarm... now i can remind myself to take brakes.
Script in post 8 (the gui-version) now has a "play-alarm" option. Plays via cvlc (the command line version of vlc...so no gui pops up.) Easy to switch it to vlc if you'd like the GUI to pop up. If you prefer rythmbox / banshee ect it should be pretty easy to swap in the appropriate program command.
As default it plays the crunchbang login sound file. Easily switch this path to whatever music file (that plays in vlc) you'd like. I think it is easier to have this hardcoded in than to put up a file selection dialog (personally I don't want to switch my alarm up that much.
In addition i lowered the final countdown from 60 to 30 seconds.
Script in post 8 (the gui-version) now has a "play-alarm" option. Plays via cvlc (the command line version of vlc...so no gui pops up.) Easy to switch it to vlc if you'd like the GUI to pop up
It is getting better all the time (sung by the Beatles)
GNu/Linux: Nu nog schoner: http://linuxnogschoner.blogspot.com/ Dutch
Thanks for the updated script with alarm. It should make it relatively easy to create a good alarm.
A much cleaner version is now available in post 8.
1) less "if then" statements to avoid messiness.
2) alarm will not remove modules.
3) choose alarm: either default or music file from dialog.
4) alarm includes a pop-up dialog (in case the speakers are off.)
5) "cancel" buttons in dialogs now actually exit the program.
This is my first project--quite fun.
Last edited by jmbarnes (2010-03-23 03:18:17)
This is awesome. I can't wait to try it out. A real, genuine alarm AND hibernate/suspend tool - love it.
Alarm in Post 8 should work a bit better now.
Repeats the alarm until the dialog is dismissed.*
Default alarm path is set at beginning (easy to located / swap), canceling custom alarm enables default alarm.
Example banshee commands (commented out) that give an example of how to use alarm to stop playing music, and begin the alarm.
*Note: to stop alarm the script uses "killall" this is a harsh way to go about ending it (esp. bad if you're doing something else in vlc at the same time the alarm goes off). Could use a vlc-stop command instead, but this would leave the program running...thoughts?
Damn! This puppy just gets better and better. Thanks Jm! I've been using it several times a day using all the functions. I use the alarm function the most frequently @ work to help with deadlines. It's set as a keybind, so I just pop it up, answer the dialogues, and forget it. Then it plays a nice tune to alert me the deadline is up - Awesome. Really appreciate it.
It's funny that a simple program like this appears to have eluded Linux. There are programs, but they are mostly either clunky, hamstringed, or butt ugly. But this is nice and simple/elegant.
Also you must have ESP. I was also trying to come up with a way to make the alarm music shut off. But your method is much mo better. Sorry I don't know how to do without the killall.
One concern is if someone is playing a movie and vlc and also goes over to set an alarm from your script. If the alarm goes off and they kill the noise, it may end up killing the movie they are watching AND the alarm sound. I think that's the risk of using killall vlc.
So it might be prudent to catch the pid of the specific vlc your script plays, and use kill to kill that specific PID. That way you won't risk whacking a separate instance of vlc. I'm not sure if that could happen, but I wonder about it. I'm pretty sure you can catch the last process enacted from a script into a variable and then later run a "kill $vlcpid" type of thing. But not sure how to code that type of thing. I think it's be something like VLCPID=$! - I believe $! represents that last process called by the script, so you'd have to catch it and store immediately after calling vlc. Then later, if the user did want to stop the music from the alarm, using that variable, you could more precisely stop the scripts instance of vlc only - I think.
But you probably know better ways to do the above, and if it's even necessary.
Anyways, keep up the awesome work!
Never caught PID's in a bash script before---very easy. Script updated so that it only kills the necessary instance of vlc. See the first post for the most up-to-date code.
Thanks for the idear.
Last edited by jmbarnes (2010-03-25 18:55:40)
thanks for the script....
i already made a "shutdown in 30 minutes" option in the openbox menu... but there is no visual countdown and you can't cancel it. this is much better.
i would like a shutdown option...
i used: echo "$pass" | sudo -S shutdown now
but i'm not sure if this is the right thing to do. i also don't know what to do with the modprobe in this case....
Privacy & Security on #!
Good idea on the shutdown. Personally I don't use it much, but this might as well work as a generic timer for all those things that the basic logout script does. As you don't need to remove modules when doing a shutdown (at least i've never heard of such) a simple if, then loop with an exit before the sleeping-bit works fine.
See the pastebin for an updated version with shutdown.
Last edited by jmbarnes (2010-03-31 14:27:51)
Thanks for the update... it's working great...
I bypassed the password check by adding exceptions to the sudoers file, but it seems a dangerous thing to do.
Maybe there is another way of doing this, as you don't need a password for oblogout.
Privacy & Security on #!