2016-01-23 4 views
0

У меня есть некоторые демоны python для приложений paspon pi, запущенных при запуске с помощью init-скриптов.Демон python запускается правильно с init-script, но сбой при запуске

Скрипт инициализации отлично работает с консоли, правильно запускает и завершает фоновый процесс.

Сценарий был сделан автозапуск с Судо insserv GartenwasserUI

Она начинается на старте, что является доказательством того, при наличии ЖК-подсветки, но не в списке процессов после входа в систему. Начало работы с sudo-сервисом GartenwasserUI начинается сразу же.

Что может быть неправильным?

Здесь сценарий

#!/bin/sh 

### BEGIN INIT INFO 
# Provides:   GartenwasserUI 
# Required-Start: $remote_fs $syslog 
# Required-Stop:  $remote_fs $syslog 
# Default-Start:  2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: GartenwasserUI acts as a mqtt client for LCD displaying and switching gpio through mqtt 
# Description:  Put a long description of the service here 
### END INIT INFO 

# Change the next 3 lines to suit where you install your script and what you want to call it 
DIR=/usr/local/bin/Gartenwasser 
DAEMON=$DIR/GartenwasserUI.py 
DAEMON_NAME=GartenwasserUI 

# Add any command line options for your daemon here 
DAEMON_OPTS="" 

# This next line determines what user the script runs as. 
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python. 
DAEMON_USER=root 

# The process ID of the script when it runs is stored here: 
PIDFILE=/var/run/$DAEMON_NAME.pid 

. /lib/lsb/init-functions 

do_start() { 
    log_daemon_msg "Starting system $DAEMON_NAME daemon" 
    cd $DIR 
    #python ./$DAEMON_NAME.py & 
    start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS --verbose -stdout /var/log/GartenwasserUI.log 
    log_end_msg $? 
} 
do_stop() { 
    log_daemon_msg "Stopping system $DAEMON_NAME daemon" 
    start-stop-daemon --stop --pidfile $PIDFILE --retry 10 
    log_end_msg $? 
} 

case "$1" in 

    start|stop) 
     do_${1} 
     ;; 

    restart|reload|force-reload) 
     do_stop 
     do_start 
     ;; 

    status) 
     status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $? 
     ;; 

    *) 
     echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}" 
     exit 1 
     ;; 

esac 
exit 0 

И сам скрипт:

#!/usr/bin/env python 

__author__ = "Bernd Gewehr" 

# import python libraries 
import os 
import signal 
import sys 
import time 

# import libraries 
import lib_mqtt as MQTT 
from Adafruit_CharLCDPlate import Adafruit_CharLCDPlate 

#DEBUG = False 
DEBUG = True 

MQTT_TOPIC_IN = "/Gartenwasser/#" 
MQTT_TOPIC = "/Gartenwasser" 
MQTT_QOS = 0 

VALVE_STATE = [0, 0, 0, 0, 0] 

def on_message(mosq, obj, msg): 
    """ 
    Handle incoming messages 
    """ 
    topicparts = msg.topic.split("/") 

    if DEBUG: 
     print msg.topic 
     print topicparts 
     for i in range(0,len(topicparts)): 
      print i, topicparts[i] 
     print msg.payload 

    pin = int('0' + topicparts[len(topicparts) - 1]) 
    value = int(msg.payload) 

    if topicparts[2] == "in": 
     if pin == 29: 
      VALVE_STATE[0] = value 
     if pin == 31: 
      VALVE_STATE[1] = value 
     if pin == 33: 
      VALVE_STATE[2] = value 
     if pin == 35: 
      VALVE_STATE[3] = value 

    Message = 'V1: ' + str(VALVE_STATE[0]) + ' V2: ' + str(VALVE_STATE[1]) + '\nV3: ' + str(VALVE_STATE[2]) + ' V4: ' + str(VALVE_STATE[3]) 
    lcd.clear() 
    lcd.message(Message) 


# End of MQTT callbacks 


def cleanup(signum, frame): 
    """ 
    Signal handler to ensure we disconnect cleanly 
    in the event of a SIGTERM or SIGINT. 
    """ 
    # Cleanup modules 
    MQTT.cleanup() 
    lcd.stop() 

    # Exit from application 
    sys.exit(signum) 


def loop(): 
    """ 
    The main loop in which we mow the lawn. 
    """ 
    while True: 
     time.sleep(0.08) 
     buttonState = lcd.buttons() 
     for b in btn: 
      if (buttonState & (1 << b[0])) != 0: 
       if DEBUG: print 'Button pressed for GPIO ' + str(b[1]) 
       if b[1] > 0: MQTT.mqttc.publish(MQTT_TOPIC + '/in/' + str(b[1]), abs(VALVE_STATE[b[2]]-1), qos=0, retain=True) 
       time.sleep(.5) 
       break 



# Use the signal module to handle signals 
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]: 
    signal.signal(sig, cleanup) 

# Initialise our libraries 
lcd = Adafruit_CharLCDPlate() 
lcd.backlight(True) 

MQTT.init() 
MQTT.mqttc.on_message = on_message 
MQTT.mqttc.subscribe(MQTT_TOPIC_IN, qos=MQTT_QOS) 

# Clear display and show greeting, pause 1 sec 
lcd.clear() 
lcd.message("Gartenwasser\nstartet...") 
time.sleep(1) 
Message = 'V1: ' + str(VALVE_STATE[0]) + ' V2: ' + str(VALVE_STATE[1]) + '\nV3: ' + str(VALVE_STATE[2]) + ' V4: ' + str(VALVE_STATE[3]) 
lcd.clear() 
lcd.message(Message) 

# Cycle through backlight colors 
#col = (lcd.RED, lcd.YELLOW, lcd.GREEN, lcd.TEAL, 
#  lcd.BLUE, lcd.VIOLET, lcd.WHITE, lcd.OFF) 
#for c in col: 
# lcd.ledRGB(c) 
# sleep(.5) 

# assign GPIO & Status index of VALVA_STATUS 

btn = ((lcd.LEFT, 29, 0), 
     (lcd.UP, 31, 1), 
     (lcd.DOWN, 33, 2), 
     (lcd.RIGHT, 35, 3), 
     (lcd.SELECT, 0, 4)) 

# start main procedure 
loop() 
+0

Идеи: предположим, что вы проверили файл '.log'. Может быть, установите 'sys.stderr = sys.stdout' при запуске в случае, если python печатает что-то полезное на stderr при выходе. Наконец, я бы побежал под «strace», чтобы узнать, как он вышел и что произошло до этого. (Нужно выяснить, как перенаправить stderr для этого, так как там будет написано 'strace', что-то вроде' strace/usr/local/bin/python