2013-08-06 27 views
6

Tôi có một tập lệnh python giải mã đầu vào từ thiết bị USB và gửi lệnh đến tập lệnh php. Kịch bản hoạt động tốt đẹp khi chạy từ giao diện điều khiển, nhưng tôi cần nó chạy khi khởi động.chạy tập lệnh python liên tục từ systemd?

Tôi đã tạo một dịch vụ hệ thống để bắt đầu tập lệnh, có vẻ hoạt động tốt, ngoại trừ quy trình systemctl start service-name không bao giờ trả về tôi cho lời nhắc lệnh. Trong khi nó đang chạy, tôi có thể tương tác với thiết bị đầu vào, chính xác như mong đợi. Tuy nhiên, nếu tôi thoát khỏi quy trình systemctl start với ctr-z, tập lệnh chỉ chạy trong vài giây.

Dưới đây là file .service mà tôi đã viết:

[Unit] 
After=default.target 

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

[Install] 
WantedBy=default.target 

và đây là kịch bản python của tôi:

#!/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() 

làm thế nào để làm cho kịch bản chạy không đồng bộ từ các tập tin dịch vụ, do đó lệnh bắt đầu có thể hoàn thành và tập lệnh có thể tiếp tục chạy trong nền?

+0

Nếu bạn thêm một '&' vào cuối dòng 'ExecStart' thì sao? Điều đó sẽ không buộc kịch bản phải chạy trong nền? [Ví dụ] (http://bashitout.com/2013/05/18/Ampersands-on-the-command-line.html). – wflynny

+0

@Chỉ cần thử phiên bản cực đoan của 'ExecStart =/usr/bin/python /root/pidora-keyboard.py &>/dev/null & ', và nó vẫn bị treo, và nếu tôi giết nó, tiến trình con sẽ được bị giết vài giây sau đó. –

+0

Điều gì về 'Type = forking' trong' [Service] '? Nếu bạn làm điều này, bạn có lẽ nên loại bỏ '&' là tốt. – wflynny

Trả lời

1

Còn về usig nohup thì sao? http://en.wikipedia.org/wiki/Nohup nohup là lệnh POSIX để bỏ qua tín hiệu HUP (gác máy). Tín hiệu HUP (gác máy) theo quy ước cách một thiết bị đầu cuối cảnh báo các quá trình đăng xuất phụ thuộc.

3

Bạn đã chỉ định cả hai After=default.targetWantedBy=default.target. Điều này không thể giải quyết được.

WantedBy chỉ định rằng mục tiêu sẽ bao gồm dịch vụ này khi khởi động, nhưng sau khi có nghĩa là để đảm bảo rằng mục tiêu được đặt tên là trước khi bắt đầu dịch vụ này!

Rất có thể bạn làm không cần After=default.target và nên xóa mục này.


Tôi cũng khuyên bạn nên chỉ định dịch vụ Type= một cách rõ ràng. Mặc dù hiện tại mặc định là simple (hoạt động cho những gì bạn đang làm) các phiên bản cũ hơn của systemd có thể có hành vi khác nhau.

[Service] 
Type=simple