systemd服务中执行notify-send无弹窗问题求助
notify-send Not Working in systemd Services I’ve run into this exact head-scratcher before—systemd services operate in a stripped-down, non-graphical environment by default, which lacks the critical context notify-send needs to pop up notifications on your desktop. Let’s break down why this happens and walk through practical fixes:
Why It’s Failing
When you run notify-send in your terminal, it relies on two key environment variables tied to your graphical session:
DISPLAY: Tells the tool which screen to send the notification to (usually:0for your main monitor)DBUS_SESSION_BUS_ADDRESS: Connects it to your desktop’s notification daemon via the D-Bus session bus
Systemd services (even those running as your user) don’t inherit these variables automatically. Without them, notify-send runs silently with no errors—exactly what you’re seeing.
Solutions to Try
1. Explicitly Set Environment Variables in Your Python Script
First, grab your current session’s values by running these in your terminal:
echo $DISPLAY echo $DBUS_SESSION_BUS_ADDRESS echo $(id -u) # Get your user ID (UID)
Then update your Python code to inject these variables before calling notify-send:
import subprocess import os # Match these values to what you got from the terminal os.environ['DISPLAY'] = ':0' os.environ['DBUS_SESSION_BUS_ADDRESS'] = 'unix:path=/run/user/1000/bus' # Replace 1000 with your UID subprocess.Popen(['notify-send', "Authentication", "True/False"])
2. Configure Your systemd Service to Inherit Session Context
Modify your systemd service file to include the required environment variables. Here’s how:
- Open your service file (e.g.,
~/.config/systemd/user/my-notify.servicefor a user service, or/etc/systemd/system/my-notify.servicefor a system-wide service) - Add these lines under the
[Service]section:
# Auto-inject the user's session bus path (%U = current user's UID) Environment=DISPLAY=:0 Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%U/bus
- Reload systemd and restart the service:
# For user services systemctl --user daemon-reload systemctl --user restart my-notify.service # For system-wide services (run as root) systemctl daemon-reload systemctl restart my-notify.service
3. Switch to a User Service (Recommended)
If you’re running the service as a system-wide service (root), move it to a user service instead. User services run in your personal session context and automatically inherit the graphical environment variables you need.
- Move your service file to
~/.config/systemd/user/ - Enable and start it with:
systemctl --user enable my-notify.service systemctl --user start my-notify.service
Quick Debug Check
To confirm the environment variables are set correctly in your service, add this line to your Python script to log values to a file:
with open('/tmp/service-env.log', 'w') as f: f.write(f"DISPLAY: {os.environ.get('DISPLAY', 'NOT SET')}\n") f.write(f"DBUS_SESSION_BUS_ADDRESS: {os.environ.get('DBUS_SESSION_BUS_ADDRESS', 'NOT SET')}\n")
Check /tmp/service-env.log after running the service to verify the variables are present.
内容的提问来源于stack exchange,提问作者Wajahat

