0

I have a python script to switch light/dark mode.

At the end there's this line:

process = subprocess.Popen(binDir + "/polybar.sh")

That script it points to is this:

#!/bin/env bash

# Terminate already running bar instances
killall -q polybar
polybar >/dev/null 2>/dev/null

If I execute the light/dark script from terminal it works perfectly, polybar gets killed and then relaunched.

However, I want a service to automatically switch depending on the time of the day, so I made some systemd timers. The light/dark script gets executed, most of the stuff in it works, but this in particular doesn't, it just kills polybar and it doesn't launch again. The systemd service is a user service.

I don't know how to troubleshoot this, systemctl status is not providing any info.

Why would a script work fine when launched from terminal, but not from systemd?

Here is the service file:

[Unit]
Type=simple
Description=dark mode
Environment="PATH=/home/{{ user }}/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/home/{{ user }}/bin"
WorkingDirectory=/home/{{ user }}/bin

[Service]
ExecStartPre=/usr/bin/brightnessctl s 200
ExecStart=/usr/bin/python /home/ger/bin/nutra.py dark

And the timer:

[Unit]
Description=Turn screen dark/light at certain times

[Timer]
OnCalendar=*-*-* 18:13:00
Persistent=true


[Install]
WantedBy=timers.target
6
  • 1
    How is bindir defined in the python script and is $PATH set differently between the systemd and interactive environments?
    – doneal24
    Sep 3 at 18:53
  • binDir = os.path.expanduser('~') + "/bin" After reading a stackexchange answer, I added this to the systemd service: Environment="PATH=/home/{{ user }}/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/home/{{ user }}/bin" However it didn't help. Sep 4 at 4:13
  • The light/dark script gets executed, most of the stuff in it works, but this in particular doesn't, it just kills polybar and it doesn't launch again. The systemd service is a user service. I don't know how to troubleshoot this, systemctl status is not providing any info. To properly answer that you should provide the contents of both the timer and service units you used.\ My educated guess is that you used RemainAfterExit=true in the service file. Sep 4 at 21:39
  • I don't know polybar. You could redirect the polybar output to a file, to see the messages, and post it here (e.g. run polybar > /home/username/polybar.log instead of polybar &>/dev/null). Most GUI applications require the environment var DISPLAY=:0 Try to add export DISPLAY=:0 to your shell script below the shebang.
    – Michael D.
    Sep 4 at 23:25
  • Maybe polybar --reload is enough to reload new settings ... To get the results with journalctl -t polybar. Run polybar --reload | systemd-cat -t polybar
    – Michael D.
    Sep 4 at 23:31

1 Answer 1

0

Jobs run through cron, or startup scripts, or systemd scripts, aren't run in the same runtime environment that you have on your desktop. Startup scripts are run as root. None of your PATH changes, or other environment variable settings from ~/.bashrc are automatically propagated to your cron job. For example, there's no $DISPLAY, so GUI programs need special treatment (read man xhost).

One can set environment variables for all one's cron jobs in the crontab file Read man 5 crontab.

Look at the results of echo "=== id ===";id;echo "=== set ===";set;echo "=== env ===";env | sort;echo "=== alias ===";alias in each of your environments.
An easy way is to store the commands in a bash script, and execute it from your terminal session, saving the output, then, execute the script from the "other" environment, saving the output. Compare the saved outputs using diff.

echo "=== id ===";id
echo "=== set ===";set
echo "=== env ===";env | sort
echo "=== alias ===";alias`

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .