I’m trying to create a systemd (user) timer that opens certain tabs every day at 9PM with xdg-open
. Here are the files:
/home/me/.config/systemd/user/test.service
[Unit] Description=Test [Service] Type=simple Environment=DISPLAY=:0 ExecStart=/bin/bash /home/me/test.sh
/home/me/.config/systemd/user/test.timer
[Unit] Description=Test Timer RefuseManualStart=no RefuseManualStop=no [Timer] Persistent=true OnCalendar=*-*-* 21:00:00 [Install] WantedBy=timers.target
/home/me/test.sh
#!/bin/bash websites=( "http://unix.stackexchange.com/" "http://stackoverflow.com/" ) for i in "${websites[@]}" do # works with /usr/bin/firefox /usr/bin/xdg-open "$i" done
This doesn’t open anything.
When I replace xdg-open
with firefox
in the above file, the tabs get opened. However, when I execute xdg-open "http://unix.stackexchange.com/"
in a terminal it opens a tab in Firefox.
systemctl --user start test.service systemctl --user status test.service
prints:
● test.service - Test Loaded: loaded (/home/me/.config/systemd/user/test.service; static; vendor preset: enabled) Active: inactive (dead) Jun 29 15:06:59 me-PC systemd[1513]: Started Test.
How can I make this timer work with xdg-open
?
Answer
Often differences between running a script manually and running it via systemd are due differences in the environment. Before the xdg-open
call, add the command env
on it’s own line, which dumps the environment.
Now run the test manually and via systemd
. Look for other variables besides DISPLAY
that could be causing the difference. By continuing to add environment variables into the systemd
script, you should be able to find the ones systemd
needs to make this work.
Your bash code in your test looks fine, but here’s a revision that’s a bit more idiomatic if you are interested. bash
naturally splits on space and URLs don’t contain space, so this alternate code works. I’ve also replaced do/done
with braces:
websites=" http://unix.stackexchange.com/ http://stackoverflow.com/" for i in $websites; { # works with /usr/bin/firefox /usr/bin/xdg-open "$i" }