You are not logged in.
Pages: 1
I've been trying to set up an alarm clock using systemd.
The alarm timer is:
[Unit]
Description=Weekend alarm
[Timer]
OnCalendar=Sat,Sun *-*-* 07:04:00
[Install]
WantedBy=timers.targetThe alarm service is
[Unit]
Description=Weekend Alarm
[Service]
Type=oneshot
ExecStart=/usr/bin/exo-open --launch TerminalEmulator AlarmClock "Weekend Alarm" "${HOME}/Music/Rainforest.mp3"
User=nobody
Group=WheelAnd, for reference, the executable is
#!/bin/bash
# Bash to play and display alarm clock message and sound from systemd.timers
# ### ### ### Constants and variables ### ### ###
DefaultSound="${HOME}/Music/Rainforest.mp3"
Count="1"
Key="Dummy"
Snooze="5s"
# ### ### ### Setup ### ### ###
# set $Mesg
if [[ $1 == "" ]] ; then
Mesg="Test"
else
Mesg="$1"
fi
# set $Music
if [[ $2 == "" ]] ; then
Music="$DefaultSound"
else
Music="$2"
fi
# set title of terminal
Title="| $Mesg Alarm"
echo -n -e "\033]0;$Title\007"
# ### ### ### Main ### ### ###
while ! [[ ${Key^^} == "F" ]] ; do
echo
echo
echo "$Mesg alarm, count=$Count. Press (Q) to silence"
mpg123 -Cq "$Music"
echo "(F)inish alarm, or (O)ther to sleep"
read -n1 -s Key
if ! [[ ${Key^^} == "F" ]] ; then
((Count++))
echo "Sleeping zzzzzzz"
sleep "$Snooze"
fi
echo
echo
echo
done
echo "Bye :)"This last has been thoroughly tested as a standalone, it is just not being launched by systemd.
After each test, I checked systemctl status for WeekendAlarm.timer
$ systemctl status WeekendAlarm.timer
● WeekendAlarm.timer - Weekend alarm
Loaded: loaded (/etc/systemd/system/WeekendAlarm.timer; enabled; vendor preset: disabled)
Active: inactive (dead)
Trigger: n/a
$ The latest results for WeekendAlarm.service are
$ systemctl status WeekendAlarm.service
● WeekendAlarm.service - Weekend Alarm
Loaded: loaded (/etc/systemd/system/WeekendAlarm.service; static; vendor preset: disabled)
Active: inactive (dead)
May 19 06:41:18 mine systemd[1]: /etc/systemd/system/WeekendAlarm.service:6: Executable path is not absolute: exo-open >
May 19 06:53:38 mine systemd[1]: /etc/systemd/system/WeekendAlarm.service:6: Unbalanced quoting, ignoring: "/usr/bin/ex>
May 19 06:54:22 mine systemd[1]: /etc/systemd/system/WeekendAlarm.service:6: Unbalanced quoting, ignoring: "/usr/bin/ex>
lines 1-7/7 (END)
$After correcting the various errors in WeekendAlarm.service, I have been resetting the time and running sudo systemctl daemon-reload. As you can see, even though the last timer was set at 07:04:00 there were no error messages after 06:54:22
Listing my timers, I get
$ systemctl list-timers -all
NEXT LEFT LAST PASSED UNIT ACTIVATES
Sat 2018-05-19 19:08:42 BST 11h left Fri 2018-05-18 19:08:42 BST 12h ago systemd-tmpfiles-clean.timer systemd-tmpfile>
Sun 2018-05-20 00:00:00 BST 16h left Sat 2018-05-19 00:00:11 BST 7h ago logrotate.timer logrotate.servi>
Sun 2018-05-20 00:00:00 BST 16h left Sat 2018-05-19 00:00:11 BST 7h ago man-db.timer man-db.service
Sun 2018-05-20 00:00:00 BST 16h left Sat 2018-05-19 00:00:11 BST 7h ago shadow.timer shadow.service
n/a n/a n/a n/a WeekendAlarm.timer WeekendAlarm.se>
5 timers listed.
$Does anyone have any ideas about what I have done wrong, or about a direction in which to look
Irvine
Last edited by IrvineHimself (2018-05-20 18:24:45)
Et voilà, elle arrive. La pièce, le sous, peut-être qu'il arrive avec vous!
Offline
Hello
What happens if you start the service manually:
# systemctl start WeekendAlarm.service
Does the terminal open?
What is the status then:
# systemctl status WeekendAlarm.service
Offline
Hi, thanks for your interest.
Just in case it was something to do with the globbing or paths on the line ExecStart=, I replaced all the wild-cards with literals, and changed AlarmClock to /usr/local/bin/AlarmClock
Also, to eliminate anything to do with how ExecStart= was quoted, I ran a few variations and launched them with sudo systemctl start WeekendAlarm.service
### No Quotes, no globbing
### ExecStart=/usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmClock Weekend-Alarm /home/stupidme/Music/Rainforest.mp3
[stupidme@mine ~]$ sudo systemctl status WeekendAlarm.service
● WeekendAlarm.service - Weekend Alarm
Loaded: loaded (/etc/systemd/system/WeekendAlarm.service; static; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2018-05-19 15:48:37 BST; 7s ago
Process: 835 ExecStart=/usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmClock Weekend-Alarm /home/stup>
Main PID: 835 (code=exited, status=216/GROUP)
May 19 15:48:37 mine systemd[1]: Starting Weekend Alarm...
May 19 15:48:37 mine systemd[835]: WeekendAlarm.service: Failed to determine group credentials: No such process
May 19 15:48:37 mine systemd[835]: WeekendAlarm.service: Failed at step GROUP spawning /usr/bin/exo-open: No such proce>
May 19 15:48:37 mine systemd[1]: WeekendAlarm.service: Main process exited, code=exited, status=216/GROUP
May 19 15:48:37 mine systemd[1]: WeekendAlarm.service: Failed with result 'exit-code'.
May 19 15:48:37 mine systemd[1]: Failed to start Weekend Alarm.### Single quotes, no globbing
### ExecStart='/usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmClock Weekend-Alarm /home/stupidme/Music/Rainforest.mp3'
$ sudo systemctl status WeekendAlarm.service
● WeekendAlarm.service - Weekend Alarm
Loaded: loaded (/etc/systemd/system/WeekendAlarm.service; static; vendor preset: disabled)
Active: failed (Result: exit-code) since Sat 2018-05-19 15:51:38 BST; 7s ago
Process: 2461 ExecStart=/usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmClock Weekend-Alarm /home/stu>
Main PID: 2461 (code=exited, status=216/GROUP)
May 19 15:51:38 mine systemd[1]: Starting Weekend Alarm...
May 19 15:51:38 mine systemd[2461]: WeekendAlarm.service: Failed to determine group credentials: No such process
May 19 15:51:38 mine systemd[2461]: WeekendAlarm.service: Failed at step GROUP spawning /usr/bin/exo-open --launch Term>
May 19 15:51:38 mine systemd[1]: WeekendAlarm.service: Main process exited, code=exited, status=216/GROUP
May 19 15:51:38 mine systemd[1]: WeekendAlarm.service: Failed with result 'exit-code'.
May 19 15:51:38 mine systemd[1]: Failed to start Weekend Alarm.
$ As you can see, the difference for encapsulating and not encapsulating the exec string with quotes is
# No quotes
May 19 15:48:37 mine systemd[835]: WeekendAlarm.service: Failed at step GROUP spawning /usr/bin/exo-open: No such proce>
# with single quotes
May 19 15:51:38 mine systemd[2461]: WeekendAlarm.service: Failed at step GROUP spawning /usr/bin/exo-open --launch Term>
# I also checked with double quotes
May 19 15:53:49 mine systemd[3861]: WeekendAlarm.service: Failed at step GROUP spawning /usr/bin/exo-open --launch Term>More importantly though, there seems to be a problem with group Wheel. Just in case I had got the capitalisation wrong, I tried it with Group=wheel, and in a sign of desperation, I tried copying verbatim Group=systemd-journal from the example in the wiki. Unlike Group=Wheel, both of these naive attempts resulted in a core-dump
Thanks again for your interest
Irvine
Et voilà, elle arrive. La pièce, le sous, peut-être qu'il arrive avec vous!
Offline
As you want this window to appear in your running session, you should be using a user service instead of a system service https://wiki.archlinux.org/index.php/Systemd/User
As it stands you would try to open up a connection to your own session from a completely unrelated context (not the same user nor the same group) that isn't going to work comfortably. Unless you went from recommended conventions, your group will be called wheel and not Wheel . Either way this is the wrong approach, set up an user service, it will run in the correct context.
Offline
Okay, I disabled and removed all my previous efforts from /etc/systemd/system/ and placed WeekendAlarm.timer along with WeekendAlarm.service in ~/.config/systemd/user/
After editing the files to replacing Group=Wheel with Group=wheel and set a new time, to make sure there were no surprises, I ran
systemctl --user import-environmentAnd checked with
$ systemctl --user show-environment
COLORTERM=truecolor
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus
DISPLAY=:0.0
GTK_MODULES=canberra-gtk-module
HOME=/home/stupidme
LANG=en_GB.UTF-8
LOGNAME=stupidme
MAIL=/var/spool/mail/stupidme
MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins
PATH=/usr/local/bin/FjSymlinks:/usr/local/sbin:/usr/local/bin:/usr/bin:/opt/cuda/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bi>
PWD=/home/stupidme
SHELL=/bin/bash
SHLVL=4
TERM=xterm-256color
USER=stupidme
VTE_VERSION=5201
WINDOWID=54525955
WINDOWPATH=2
XAUTHORITY=/tmp/.XauthHAs9Wc
XDG_RUNTIME_DIR=/run/user/1001
XDG_SEAT=seat0
XDG_SESSION_ID=1
XDG_VTNR=2
_=/usr/bin/systemctl
lines 1-24/24 (END)
$Then, enabled the timer:
$ systemctl --user enable WeekendAlarm.timer
Created symlink /home/stupidme/.config/systemd/user/timers.target.wants/WeekendAlarm.timer → /home/stupidme/.config/systemd/user/WeekendAlarm.timer.
$Because I am new to all this, I ran
$ systemctl --user enable WeekendAlarm.service
The unit files have no installation config (WantedBy, RequiredBy, Also, Alias
settings in the [Install] section, and DefaultInstance for template units).
This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's
.wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, ...).
4) In case of template units, the unit is meant to be enabled with some
instance name specified.
$ Which I took to mean that it is being enabled by WeekendAlarm.timer?
So after running
$ systemctl --user start WeekendAlarm.service
Job for WeekendAlarm.service failed because the control process exited with error code.
See "systemctl --user status WeekendAlarm.service" and "journalctl --user -xe" for details.
$ I ran
$ systemctl --user status WeekendAlarm.service
● WeekendAlarm.service - Weekend Alarm
Loaded: loaded (/home/stupidme/.config/systemd/user/WeekendAlarm.service; static; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2018-05-19 18:35:52 BST; 19s ago
Process: 25687 ExecStart=/usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmClock Weekend-Alarm /home/stupidme/Music/Rainforest.mp3 (code=exit>
Main PID: 25687 (code=exited, status=216/GROUP)
May 19 18:35:52 mine systemd[2210]: Starting Weekend Alarm...
May 19 18:35:52 mine systemd[25687]: WeekendAlarm.service: Failed to determine supplementary groups: Operation not permitted
May 19 18:35:52 mine systemd[25687]: WeekendAlarm.service: Failed at step GROUP spawning /usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmCloc>
May 19 18:35:52 mine systemd[2210]: WeekendAlarm.service: Main process exited, code=exited, status=216/GROUP
May 19 18:35:52 mine systemd[2210]: WeekendAlarm.service: Failed with result 'exit-code'.
May 19 18:35:52 mine systemd[2210]: Failed to start Weekend Alarm.Which I understand to mean that there is still some kind of problem with Group
For reference, since WeekendAlarm.timer and WeekendAlarm.service have been edited slightly since I originaly posted them:
WeekendAlarm.timer
[Unit]
Description=Weekend alarm
[Timer]
OnCalendar=Sat,Sun *-*-* 18:40:00
[Install]
WantedBy=timers.targetWeekendAlarm.service
[Unit]
Description=Weekend Alarm
[Service]
Type=oneshot
ExecStart="/usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmClock Weekend-Alarm /home/stupidme/Music/Rainforest.mp3"
User=nobody
Group=wheelThanks for your thoughts
Irvine
Et voilà, elle arrive. La pièce, le sous, peut-être qu'il arrive avec vous!
Offline
First, why do you have User and Group in there at all? Get rid of them.
Second, do not quote ExecStart unless you want systemd to try to exec a binary with the name of the full string in quotes (you don't).
Third, you need to set at least a DISPLAY variable to the environment to run an X11 program from a systemd service.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Trilby, Thanks, I am starting to make some real progress here.
First, why do you have User and Group in there at all? ....
This is completely new territory for me, I was just following the example in the Wiki's timer example. By the way, I am not blaming the Wiki, I am blaming my inexperience.
....Second, do not quote ExecStart unless you want systemd to try to exec a binary with the name of the full string in quotes (you don't)...
Initially, I didn't quote the ExecStart string. Recognising I should have been using systemctl --user ..., I was just trying interpret the errors reported by systemctl , status WeekendAlarm.service. Again it was just inexperience.
.....Third, you need to set at least a DISPLAY variable to the environment to run an X11 program from a systemd service.
After running the env comand in a terminal, I edited WeekendAlarm.service to read:
[Unit]
Description=Weekend Alarm
[Service]
Type=oneshot
ExecStart=/usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmClock Weekend-Alarm /home/stupidme/Music/Rainforest.mp3
Environment=DISPLAY=:0.0Aditionally, since I want the alarm to run every weekend, I edited WeekendAlarm.timer to add Persistent=true
[Unit]
Description=Weekend alarm
[Timer]
OnCalendar=Sat,Sun *-*-* 05:05:00
Persistent=true
[Install]
WantedBy=timers.targetIn the sense there were no reported errors, these edits worked, though I still didn't get my PopUp terminal.
$ systemctl --user status WeekendAlarm.timer
● WeekendAlarm.timer - Weekend alarm
Loaded: loaded (/home/stupidme/.config/systemd/user/WeekendAlarm.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Sat 2018-05-19 19:15:58 BST; 9h ago
Trigger: Sun 2018-05-20 04:45:00 BST; 6min left
May 19 19:15:58 mine systemd[2204]: Started Weekend alarm.
$And after running systemctl --user start WeekendAlarm.service
$ systemctl --user status WeekendAlarm.service
● WeekendAlarm.service - Weekend Alarm
Loaded: loaded (/home/stupidme/.config/systemd/user/WeekendAlarm.service; static; vendor preset: enabled)
Active: inactive (dead) since Sun 2018-05-20 04:35:13 BST; 3min 18s ago
Main PID: 29181 (code=exited, status=0/SUCCESS)
May 20 04:35:13 mine systemd[2204]: Starting Weekend Alarm...
May 20 04:35:13 mine systemd[2204]: Started Weekend Alarm.
$As I say though, there was no PopUp terminal window.
Anyway to make sure I hadn't missed anything I ran systemctl --user import-environment, and got the expected gtk warnings about things being depreciated, but still no PopUp
$ systemctl --user status WeekendAlarm.timer
● WeekendAlarm.timer - Weekend alarm
Loaded: loaded (/home/stupidme/.config/systemd/user/WeekendAlarm.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Sat 2018-05-19 19:15:58 BST; 9h ago
Trigger: Sun 2018-05-20 05:05:00 BST; 4min 12s left
May 19 19:15:58 mine systemd[2204]: Started Weekend alarm..
$
$
$ systemctl --user status WeekendAlarm.service
● WeekendAlarm.service - Weekend Alarm
Loaded: loaded (/home/stupidme/.config/systemd/user/WeekendAlarm.service; static; vendor preset: enabled)
Active: inactive (dead) since Sun 2018-05-20 05:05:58 BST; 33min ago
Process: 12646 ExecStart=/usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmClock Weekend-Alarm /home/stupidme/Music/Rainforest.mp3 (code=exit>
Main PID: 12646 (code=exited, status=0/SUCCESS)
May 20 05:05:58 mine systemd[2204]: Starting Weekend Alarm...
May 20 05:05:58 mine exo-open[12646]: Theme parsing error: gtk.css:63:28: The :prelight pseudo-class is deprecated. Use :hover instead.
May 20 05:05:58 mine exo-open[12646]: Theme parsing error: gtk.css:73:35: The :prelight pseudo-class is deprecated. Use :hover instead.
May 20 05:05:58 mine exo-open[12646]: Theme parsing error: gtk.css:115:31: The :insensitive pseudo-class is deprecated. Use :disabled instead.
May 20 05:05:58 mine exo-open[12646]: Theme parsing error: gtk.css:116:24: The :insensitive pseudo-class is deprecated. Use :disabled instead.
May 20 05:05:58 mine exo-open[12646]: Theme parsing error: gtk.css:145:27: The :insensitive pseudo-class is deprecated. Use :disabled instead.
May 20 05:05:58 mine exo-open[12646]: Theme parsing error: gtk.css:146:29: The :insensitive pseudo-class is deprecated. Use :disabled instead.
May 20 05:05:58 mine exo-open[12646]: Theme parsing error: gtk.css:166:34: The :insensitive pseudo-class is deprecated. Use :disabled instead.
May 20 05:05:58 mine exo-open[12646]: Theme parsing error: gtk.css:187:34: The :inconsistent pseudo-class is deprecated. Use :indeterminate instead.
May 20 05:05:58 mine systemd[2204]: Started Weekend Alarm.
$I have been studying the systemd/User page, and, apart from the big "Why am I not getting my PopUp Terminal?", I have a few questions.
1) I checked for the /etc/X11/xinit/xinitrc.d/50-systemd-user.sh and, since it was present, to make sure it was working, I rebooted and ran systemctl --user show-environment, which shows that, by default, systemd --user has the following minimal environment:
$ systemctl --user show-environment
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus
DISPLAY=:0
HOME=/home/stupidme
LANG=en_GB.UTF-8
LOGNAME=stupidme
MAIL=/var/spool/mail/stupidme
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin
SHELL=/bin/bash
USER=stupidme
XAUTHORITY=/tmp/.XauthlcR7WL
XDG_RUNTIME_DIR=/run/user/1001
$This being the case, do I actually need to worry about XAUTHORITY and DISPLAY in my *.service files?.... As a quick check, I commented out #Environment=DISPLAY=:0.0 and it didn't seem to make any difference
$ systemctl --user show-environment
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus
DISPLAY=:0
HOME=/home/stupidme
LANG=en_GB.UTF-8
LOGNAME=stupidme
MAIL=/var/spool/mail/stupidme
PATH=/usr/local/sbin:/usr/local/bin:/usr/bin
SHELL=/bin/bash
USER=stupidme
XAUTHORITY=/tmp/.XauthP6ExjT
XDG_RUNTIME_DIR=/run/user/1001
$
$ systemctl --user status WeekendAlarm.timer
● WeekendAlarm.timer - Weekend alarm
Loaded: loaded (/home/stupidme/.config/systemd/user/WeekendAlarm.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Sun 2018-05-20 06:38:55 BST; 8min ago
Trigger: Sat 2018-05-26 06:40:00 BST; 5 days left
May 20 06:38:55 mine systemd[2207]: Started Weekend alarm.
$
$ systemctl --user start WeekendAlarm.service
$
$ systemctl --user status WeekendAlarm.service
● WeekendAlarm.service - Weekend Alarm
Loaded: loaded (/home/stupidme/.config/systemd/user/WeekendAlarm.service; static; vendor preset: enabled)
Active: inactive (dead) since Sun 2018-05-20 06:47:14 BST; 8s ago
Process: 6545 ExecStart=/usr/bin/exo-open --launch TerminalEmulator /usr/local/bin/AlarmClock Weekend-Alarm /home/stu>
Main PID: 6545 (code=exited, status=0/SUCCESS)
May 20 06:47:14 mine systemd[2207]: Starting Weekend Alarm...
May 20 06:47:14 mine systemd[2207]: Started Weekend Alarm.
lines 1-8/8 (END)2) In the section on PATH the wiki article talks about adding environmental variables to .bash_profile. Am I correct in thinking I could use systemctl --user import-environment * in my Openbox autostart to add environmental variables to systemd --user?
Thanks to all for their help and patience,
Irvine
Et voilà, elle arrive. La pièce, le sous, peut-être qu'il arrive avec vous!
Offline
Major breakthrough!!!!
I was trying various ideas and using the Task manager. While they didn't work, one of my failures gave me the idea of trying it without /usr/bin/exo-open. So I edited ExecStart= to read:
ExecStart=/usr/local/bin/AlarmClock Weekend-Alarm /home/stupidme/Music/Rainforest.mp3Also, I added
# debug
notify-send -u NORMAL -t 10000 "Alarm Clock Working" --icon="${HOME}/Pictures/LauncherIcons/Bash.png"This works, it plays the required music and notify-send displays the required message. Now if I can just figure out how to get some input/ouput capability...... Alternatively, I could use systemd to launch a bash which runs as a shell /usr/bin/exo-open.... ????
Anyway, I have real world concerns to take care of, but will keep you posted
Irvine
Et voilà, elle arrive. La pièce, le sous, peut-être qu'il arrive avec vous!
Offline
First, Persistent=true does not mean it repeats - it will do that anyways. Persistent=true means that if your computer if off at 5:05am on a weekend, the timer will trigger the next time the system is turned on (probably not what you want).
For the last posts it now looks like your timer is working and you are right to focus on debugging your ExecStart command. I hadn't dug into that earlier as it's best to work one step at a time. But the original ExecStart commands seemed needlessly complex to me to start with. Why were you using exo-open in the first place?
When you got rid of exo-open you also got rid of the terminal emulator, so there's no surpise that this doesn't launch a terminal. You have two choices, one to put whatever terminal you want in the ExecStart command, e.g.:
ExecStart=/usr/bin/urxvt -c /usr/local/bin/AlarmClock ...Alternatively, if this 'AlarmClock' script isn't called from other places, just put the call to the terminal in the script itself.
Following from that point you pass parameters to your script, but at least the audo file is the default, so it's really not needed.
As for the script itself, it should work as-is (I think) but it's also far more complex than it needs to be. You should at least get rid of the if blocks for setting default parameters. Consider this:
#!/bin/bash
Mesg=${1:-Test}
Music=${2:-$HOME/Music/Rainforest.mp3}
Snooze=5s
printf '\033]0;| %s Alarm\007' "$Mesg"
while [[ $((Count++)) ]]; do
printf '\n\n%s alarm, count=%d. Press (Q) to silence\n' "$Mesg" $Count
mpg123 -Cq "$Music"
read -n1 -s -p '(F)inish alarm, or (O)ther to sleep' Key
[[ $Key == "F" ]] && break
printf '\nSleeping zzzzzzzz\n\n\n'
sleep $Snooze
done
printf '\n\n\nBye ;)\n'I'd also suggest adding the -t flag to 'read', but this is not to improve the code, but rather improves function. It adds a timeout of some number of seconds. If you do not hit F or some other key, do you want your alarm clock to behave as if you are still thinking about which one to press? A better behavior would be to assume you fell back asleep and it should continue on with the alarm again. If it were me, I'd do something more like this:
#!/bin/bash
Mesg=${1:-Test}
Music=${2:-$HOME/Music/Rainforest.mp3}
Snooze=5m
Repeat=5
echo $Mesg
exit
printf '\033]0;| %s Alarm\007' "$Mesg"
while [[ $((Count++)) ]]; do
printf '\n\n%s alarm, count=%d. Press (Q) to silence\n' "$Mesg" $Count
mpg123 -Cq "$Music"
read -n1 -s -p -t $Repeat '(F)inish alarm, (S)nooze' Key
case $Key in
F) break ;;
S) printf '\nSleeping zzzzzzzz\n\n\n'; sleep $Snooze ;;
esac
done
printf '\n\n\nBye ;)\n'So if you explicitly opt for a snooze, you actually get 5 minutes but if you do not respond to the alarm at all, it goes off again in 5 seconds.
Last edited by Trilby (2018-05-20 18:33:56)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
@Trilby Thanks for that, there's a lot of that I didn't know, especially your elegant way of assigning default values when the shell parameters are empty.
The situation with exo-open is that, when, two years ago, I migrated from Windows 10 to Arch Linux, (via a thankfully brief stint with Ubuntu,) I gave myself a crash course in writing bash [shells??]. . Needless to say, when, in some my scripts, I wanted a way to run a shell in separate window, your very obvious solution escaped me. After a couple of day's searching online, I found it to be a common question; with a lot of potential solutions of which none worked! Not to be deterred, I had the brainwave of looking at how my desktop opened a terminal, (I think I was using Xfce at the time.) Anyway, largely trough inertia, exo-open became my go to solution for running a shell in a new terminal.
But, back to the problem in hand. You are correct, my original script does work as is, though I have rewritten it to incorporate your insights.
For reference, here are the final working versions of WeekendAlarm.timer, WeekendAlarm.service and AlarmClock
WeekendAlarm.timer
[Unit]
Description=Weekend alarm
[Timer]
OnCalendar=Sat,Sun *-*-* 07:30:00
[Install]
WantedBy=timers.targetWeekendAlarm.service
[Unit]
Description=Weekend Alarm
[Service]
Type=oneshot
ExecStart=/usr/bin/xfce4-terminal -x /usr/local/bin/AlarmClock Weekend-Alarm ${HOME}/Music/Alarm-Rain.mp3
#Environment=DISPLAY=:0.0AlarmClock
#!/bin/bash
# Bash to play and display alarm clock message and sound from systemd.timers
# ### ### ### Constants and variables ### ### ###
Mesg=${1:-Test-Alarm}
Music=${2:-$HOME/Music/Alarm-Rain.mp3}
Snooze=5m
Repeat=60
Count="1"
# set title and size of terminal window
Title="| $Mesg"
printf "\033]0;$Title\007"
printf '\033[8;4;55t'
# ### ### ### Main ### ### ###
while ! [[ ${Key^^} == "F" ]] ; do
printf '\n%s alarm, count=%d. Press (Q) to silence\n' "$Mesg" $Count
mpg123 -Cq "$Music"
read -n1 -s -t $Repeat -p "(F)inish alarm, or (O)ther to sleep" Key
case $Key in
[fF]) break ;;
*) printf "\n $Mesg Sleeping zzzzzzzz\n\n\n" ; sleep $Snooze ; ((Count++)) ;;
esac
done
echo "Bye :)"Since my systemd alarm clock is both functional and, more importantly, working. I am marking the thread solved.
However, as food for thought, by using a file and a couple of nested panel launchers, I spent the afternoon trying to get the whole thing to work without a terminal. The basic technique is fairly simple and, so long as systemd is not involved, works. The problem is that as soon as you kill the sound, systemd restarts it, and stopping the service kills the executable. I have been looking at this old thread as a possible solution, but, noting I am a novice at all this, haven't really had a chance to study it.
All the best
Irvine
Last edited by IrvineHimself (2018-05-20 18:26:18)
Et voilà, elle arrive. La pièce, le sous, peut-être qu'il arrive avec vous!
Offline
Just to finish up: I've figured out how to completely dispense with the terminal and control the basic operation of my systemd alarm clock with a single mouse click.
The basic technique is probably applicable in a variety of situations, and others may find it useful. At it's core, to make an alarm sleep is as follows:
grep PidMusic
kill -SIGSTOP PidMusic
sleep
kill -SIGCONT PidMusicEssential, what happens is that the service launches the music player on an infinite loop. Then, with a couple of nested panel launchers, you can either tell the controler to sleep the music player, or stop ALL alarm services. The real trick to making it work is in prefixing any music file, along with the systemd alarm service, with "Alarm". That way, you can easily filter ps -aux and systemctl --user --type=service to get the active alarms along with the pid's of the associated music player.
For reference, the systemd exec script is:
#!/bin/bash
# Bash to play alarm clock music
# started by systemd.timers
# sleep with 'AlarmClock-Off "sleep"'
# stop with 'AlarmClock-Off "off"'
# ### ### ### Constants and variables ### ### ###
NotifyIcon="${HOME}/Pictures/LauncherIcons/AlarmClock-small.png"
Mesg=${1:-TestAlarm}
Music=${2:-$HOME/Music/Alarm-Rain.mp3}
Key="forever"
# ### ### ### Main ### ### ###
notify-send -u NORMAL -t 10000 "$Mesg" --icon="$NotifyIcon"
while ! [[ $Key == "finished" ]] ; do
mpg123 -Cq "$Music"
doneAnd the controller script is:
#!/bin/bash
# Bash to control my systemd alarm clocks
# AlarmClock-Music is started by systemd.timers
# sleep with 'AlarmClock-Off "sleep"'
# stop with 'AlarmClock-Off "off"'
# ### ### ### Constants and variables ### ### ###
NotifyIcon="${HOME}/Pictures/LauncherIcons/AlarmClock-small.png"
AlrmClckTmp="${HOME}/AlarmClock.tmp"
Action=${1:-off}
PidCount="0"
Snooze="1m"
Repeat="10"
Count="0"
function AlarmSleep() {
# Avoid any problems with the pipe by sending output to a tmp file
ps -aux | grep "mpg123" | grep "Alarm-" > "$AlrmClckTmp"
# Read pid's from file and check 'STATE' -- see man page
while IFS='' read -r PsAuxLine || [[ -n "$PsAuxLine" ]] ; do
State=$(echo $PsAuxLine | rev | cut -d':' -f3- | cut -d' ' -f2- | xargs | cut -d' ' -f1 | rev )
if ! [[ "$State" == *"T"* ]] ; then
### It's not already 'stopped', so get the 'pid'
PidArray[PidCount]=$(echo $PsAuxLine | cut -d' ' -f2- | xargs | cut -d' ' -f1 )
((PidCount++))
fi
done < "$AlrmClckTmp"
# Clean up tmp file and send them to sleep
rm -f "$AlrmClckTmp"
for Pid in ${PidArray[@]} ; do
kill -SIGSTOP "$Pid"
done
# Snooze
while ! [[ $Count == $Repeat ]] ; do
notify-send -u NORMAL -t 10000 "Sleeping zzzz" --icon="$NotifyIcon"
sleep "$Snooze"
((Count++))
done
# Wake up
for Pid in ${PidArray[@]} ; do
kill -SIGCONT "$Pid"
done
notify-send -u NORMAL -t 10000 "Awake now" --icon="$NotifyIcon"
}
function AlarmsOff() {
# Stop all alarms
systemctl --user --type=service | grep "Alarm" | cut -d' ' -f1 |\
while read AlarmService ; do
systemctl --user stop "$AlarmService"
done
}
# ### ### ### Main ### ### ###
case $Action in
"sleep") AlarmSleep ;;
"off") AlarmsOff
esacAnyway, all the best to veryone and thankyou for your help and patience
Irvine
Et voilà, elle arrive. La pièce, le sous, peut-être qu'il arrive avec vous!
Offline
FWIW that can be *drastically* simplified. Just to take one part when looking for the pid and state, you should never need to pipe grep into grep, and that line with multiple revs cuts and xargs is crazy - a single simple awk command could do all that. But more importantly you don't need to do all that filtering. If you want to stop all processes matching a criteria just do that: don't make a temp file and loop through it for no purpose:
kill -SIGSTOP $(ps aux | awk '/mpg123.*Alarm/ { print $1; }')And if you aren't running any other mpg123 processes, this would be even easier:
pkill -SIGSTOP mpg123Last edited by Trilby (2018-05-21 19:58:00)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Pages: 1