我正在为我的树莓派 pi3 制作一个电池通知程序脚本。当我这样做时脚本正在执行
/usr/bin/python /home/pi/Documents/shutdown.py
并显示弹出通知。但是该服务没有执行它或没有显示通知。如果我这样做,我可以看到 python 进程sudo systemctl status battery-notifier.service
。
电池通知程序服务
[Unit]
Description=Battery Notifier
[Service]
Type=simple
WorkingDirectory=/home/pi/Documents
ExecStart=/usr/bin/python /home/pi/Documents/shutdown.py
[Install]
WantedBy=multi-user.target
关机.py
import raspiupshat
import statistics
import subprocess
from time import sleep
raspiupshat.init()
while(True):
voltagesList = []
sleep(0.5)
currentVoltage = raspiupshat.getv()
voltagesList.append(currentVoltage)
medianVoltage = statistics.median(voltagesList)
if(medianVoltage>4):
subprocess.Popen(["notify-send","Battery Full!"])
这是我执行此操作时服务的状态sudo systemctl status battery-notifier.service
:
● battery-notifier.service - Battery Notifier
Loaded: loaded (/lib/systemd/system/battery-notifier.service; enabled)
Active: active (running) since Sat 2017-07-15 04:05:18 UTC; 48min ago
Main PID: 28384 (python)
CGroup: /system.slice/battery-notifier.service
└─28384 /usr/bin/python /home/pi/Documents/shutdown.py
Jul 15 04:05:18 raspberrypi systemd[1]: Started Battery Notifier.
答案1
编辑添加:您的程序尝试访问用户的图形桌面 ( pi
),但是,它本身是由 systemd 执行的。也就是说,它将默认以 root 身份运行,而不是以 user 身份运行pi
。此外,启动时甚至可能还没有图形桌面。
因此,你可以走几条路:
- 不是通过 systemd 启动程序,而是在登录用户启动图形桌面时启动程序。因此,您需要将程序启动放入文件
~/.xinitrc
或~/.xprofile
.看Arch Wiki 关于自动启动的内容 User=pi
向您的 systemd 服务添加一行。这是您在原始帖子的评论中提到的解决方案- systemd 可以配置为在用户登录时以用户模式(而不是系统模式)执行。您可以通过这种方式启动您的服务。看Arch Wiki 关于 systemd/User 的内容
原答案:
看这个问题。函数env=
中有一个subprocess.Popen(.)
可以使用的参数。
或者,您可以使用以下功能:sh
如果您在调用之前立即分配一个变量,则(仅)为该调用设置该变量:
myvar=world
# cannot use echo $myvar, because $myvar would be substituted before echo is launched
myvar=hello declare -x myvar
echo $myvar
给出
declare -x myvar="hello"
world
所以对你来说:
subprocess.call("DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-goOEk5dZcK,guid=9c1f14175e6be0992b16e5155969b46c notify-send 'Battery full!'",shell=True)
您在问题评论中提到的调用不起作用,因为它会导致以下过程
subprocess.Popen('export DBUS_SESSION_BUS_ADRESS=..., shell = True)
- 启动外壳
DBUS_SESSION_BUS_ADRESS=...
设置此 shell 和所有子 shell 的环境变量(就是这样export
做的)。它能做什么不是:为机器上的所有 shell 设置变量!
- 关闭外壳。现在
DBUS_SESSION_BUS_ADRESS
又失去了价值。
subprocess.Popen(['notify-send',...], shell=True)
- 启动外壳
- 前一个 shell 的调用
export
在这里没有任何作用,因为这两个 shell 完全不相关 notify-send
按照您原来的问题启动
所以环境变量的设置在这里不起作用。