systemdサービスはPythonスクリプトを実行しません。

systemdサービスはPythonスクリプトを実行しません。

私はラズベリーパイ3用のバッテリー通知スクリプトを作成しています。私がしたときにスクリプトが実行されています。

/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

shutdown.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 として実行されますpi。また、起動時にグラフィックスデスクトップがない可能性があります。

したがって、次のようないくつかのパスを選択できます。

  • systemdを介してプログラムを起動する代わりに、ログインしたユーザーがグラフィカルデスクトップを起動するとプログラムが起動します。したがって、プログラムの起動をファイル~/.xinitrcまたは~/.xprofile.seeに入れる必要があります。自動起動のArch Wiki
  • User=piシステムサービスに1行追加します。これは元の投稿のコメントで述べた解決策です。
  • ユーザーがログインしたときにシステムモードではなくユーザーモードで実行するようにsystemdを設定できます。このようにしてサービスを開始できます。バラよりsystemd/Userに関するArch Wiki

元の答え:

バラよりこの問題。関数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

POSIX仕様の対応するセクションへのリンク

だからあなたのため:

subprocess.call("DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-goOEk5dZcK,‌​guid=9c1f14175e6be09‌​92b16e5155969b46c notify-send 'Battery full!'",s‌​hell=True)

お問い合わせのコメントに記載されている通話は、次のプロセスにつながって機能しません。

  • subprocess.Popen('export DBUS_SESSION_BUS_ADRESS=..., shell = True)

    • シェルの起動
    • DBUS_SESSION_BUS_ADRESS=...このシェルとすべてのサブシェルの環境変数を設定します(これが実行される操作ですexport)。

      何ができるかいいえ:マシンのすべてのシェルの変数を設定します!

    • シェルを閉じます。今度はDBUS_SESSION_BUS_ADRESSその価値を失いました。
  • subprocess.Popen(['notify-send',...], shell=True)
    • シェルの起動
    • 以前のシェルの呼び出しは、両方のexportシェルが完全に関連していないため、ここでは効果がありません。
    • notify-send元の質問に従って始めてください。

したがって、環境変数の設定はここでは何の影響もありません。

関連情報