running a persistent python script from systemd?

11,260

Solution 1

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

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!

Most likely you do not need After=default.target and should remove this.


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.

[Service]
Type=simple

Solution 2

What about usig nohup? http://en.wikipedia.org/wiki/Nohup nohup 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.

Share:
11,260
Greg Schoppe
Author by

Greg Schoppe

Updated on June 11, 2022

Comments

  • Greg Schoppe
    Greg Schoppe over 1 year

    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.

    I created a systemd service to start the script, which appears to work well, except that the systemctl start service-name process 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 start process with ctr-z, the script only remains running for a few seconds.

    Here is the .service file that I wrote:

    [Unit]
    After=default.target
    
    [Service]
    ExecStart=/usr/bin/python /root/pidora-keyboard.py
    
    [Install]
    WantedBy=default.target
    

    and here is my python script:

    #!/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?