bash 从systemd运行持久性python脚本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18086896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:09:21  来源:igfitidea点击:

running a persistent python script from systemd?

pythonlinuxbashsystemd

提问by Greg Schoppe

I have a python script that decodes the input from a usb device and sends commands to a php script. The script works beautifully when run from the console, but I need it to be run on startup.

我有一个 python 脚本,它解码来自 USB 设备的输入并将命令发送到 php 脚本。从控制台运行时,脚本运行良好,但我需要它在启动时运行。

I created a systemd service to start the script, which appears to work well, except that the systemctl start service-nameprocess never returns me to the command prompt. While it is running, I can interact with the input device, exactly as expected. However, if I exit the systemctl startprocess with ctr-z, the script only remains running for a few seconds.

我创建了一个 systemd 服务来启动该脚本,该服务似乎运行良好,只是该systemctl start service-name过程从未将我返回到命令提示符。在它运行时,我可以完全按照预期与输入设备进行交互。但是,如果我systemctl start用 ctr-z退出进程,脚本只会保持运行几秒钟。

Here is the .service file that I wrote:

这是我写的 .service 文件:

[Unit]
After=default.target

[Service]
ExecStart=/usr/bin/python /root/pidora-keyboard.py

[Install]
WantedBy=default.target

and here is my python script:

这是我的python脚本:

#!/usr/bin/env python
import json, random
from evdev import InputDevice, categorize, ecodes
from urllib.request import urlopen

dev = InputDevice('/dev/input/event2')

def sendCommand(c):
    return json.loads(urlopen("http://127.0.0.1/api.php?command="+c).read().decode("utf-8"))
def getRandomStation():
    list = sendCommand('stationList')
    list = list['stations']
    index = random.randint(0, (len(list)-1))
    print(list[index]['id'] + " - " + list[index]['name'])
    sendCommand('s' + list[index]['id'])

print(dev)
for event in dev.read_loop():
    if event.type == ecodes.EV_KEY:
        key_pressed = str(categorize(event))
        if ', down' in key_pressed:
            print(key_pressed)
            if 'KEY_PLAYPAUSE' in key_pressed:
                print('play')
                sendCommand('p')
            if 'KEY_FASTFORWARD' in key_pressed:
                print('fastforward')
                sendCommand('n')
            if 'KEY_NEXTSONG' in key_pressed:
                print('skip')
                sendCommand('n')
            if 'KEY_POWER' in key_pressed:
                print('power')
                sendCommand('q')
            if 'KEY_VOLUMEUP' in key_pressed:
                print('volume up')
                sendCommand('v%2b')
            if 'KEY_VOLUMEDOWN' in key_pressed:
                print('volume down')
                sendCommand('v-')
            if 'KEY_CONFIG' in key_pressed:
                print('Random Station')
                getRandomStation()

how do I make the script run asynchronously from the service file, so that the start command can complete, and the script can continue running in the background?

如何让脚本从服务文件异步运行,使得启动命令可以完成,并且脚本可以在后台继续运行?

回答by Michael Hampton

You've specified both After=default.targetand WantedBy=default.target. This is not resolvable.

您已经指定了After=default.targetWantedBy=default.target。这是无法解决的。

WantedBy specifies that the target will include this service when starting up, but After means to ensure that the named target is up before starting this service!

WantedBy 指定目标在启动时会包含这个服务,而 After 的意思是在启动这个服务之前确保指定的目标是 up 的!

Most likely you do notneed After=default.targetand should remove this.

最有可能你就不会需要After=default.target和应该删除此。



I also suggest you specify the service Type=explicitly. While the default is currently simple(which should work for what you're doing) older versions of systemd may have behaved differently.

我还建议您明确指定服务Type=。虽然默认是当前simple(这应该适用于您正在做的事情),但旧版本的 systemd 可能表现得不同。

[Service]
Type=simple

回答by jmc

What about usig nohup? http://en.wikipedia.org/wiki/Nohupnohup is a POSIX command to ignore the HUP (hangup) signal. The HUP (hangup) signal is by convention the way a terminal warns dependent processes of logout.

使用 nohup 怎么样? http://en.wikipedia.org/wiki/Nohupnohup 是一个 POSIX 命令,用于忽略 HUP(挂断)信号。HUP(挂断)信号通常是终端警告注销相关进程的方式。