Daemonizing ein python-script in debian
Habe ich ein python-script, das ich ausführen möchten, die im hintergrund beim Start. Dies ist das Skript:
#!/usr/bin/python
from Adafruit_CharLCD import Adafruit_CharLCD
from subprocess import *
from time import sleep, strftime
from datetime import datetime
from datetime import timedelta
from os import system
from os import getloadavg
from glob import glob
#Variables
lcd = Adafruit_CharLCD() #Stores LCD object
cmdIP = "ip addr show eth0 | grep inet | awk '{print $2}' | cut -d/-f1" #Current IP
cmdHD = "df -h /| awk '{print $5}'" # Available hd space
cmdSD = "df -h /dev/sda1 | awk '{print $5}'" # Available sd space
cmdRam = "free -h"
temp = 0
#Run shell command
def run_cmd(cmd):
p = Popen(cmd, shell=True, stdout=PIPE)
output = p.communicate()[0]
return output
#Initalises temp device
def initialise_temp():
#Initialise
system("sudo modprobe w1-gpio")
system("sudo modprobe w1-therm")
#Find device
devicedir = glob("/sys/bus/w1/devices/28-*")
device = devicedir[0]+"/w1_slave"
return device
#Gets temp
def get_temp(device):
f = open (device, 'r')
sensor = f.readlines()
f.close()
#parse results from the file
crc=sensor[0].split()[-1]
temp=float(sensor[1].split()[-1].strip('t='))
temp_C=(temp/1000.000)
temp_F = ( temp_C * 9.0 / 5.0 ) + 32
#output
return temp_C
#Gets time
def get_time():
return datetime.now().strftime('%b %d %H:%M:%S\n')
#Gets uptime
def get_uptime():
with open('/proc/uptime', 'r') as f:
seconds = float(f.readline().split()[0])
array = str(timedelta(seconds = seconds)).split('.')
string = array[0].split(' ')
totalString = string[0] + ":" + string[2]
return totalString
#Gets average load
def get_load():
array = getloadavg()
average = 0
for i in array:
average += i
average = average / 3
average = average * 100
average = "%.2f" % average
return str(average + "%")
#def get_ram():
def get_ram():
ram = run_cmd(cmdRam)
strippedRam = ram.replace("\n"," ");
splitRam = strippedRam.split(' ')
totalRam = int(splitRam[52].rstrip("M"))
usedRam = int(splitRam[59].rstrip("M"))
percentage = "%.2f" % ((float(usedRam) / float(totalRam)) * 100)
return percentage + "%"
#Gets the SD usage
def get_sd():
sd = run_cmd(cmdSD)
strippedSD = sd.lstrip("Use%\n")
return strippedSD
#Gets the HD usage
def get_hd():
hd = run_cmd(cmdSD)
strippedHD = hd.lstrip("Use%\n")
return strippedHD
def scroll():
while(1):
lcd.scrollDisplayLeft()
sleep(0.5)
#Uptime and IP
def screen1():
uptime = get_uptime()
lcd.message('Uptime %s\n' % (uptime))
ipaddr = run_cmd(cmdIP)
lcd.message('IP %s' % (ipaddr))
#Ram and load
def screen2():
ram = get_ram()
lcd.message('Ram Used %s\n' % (ram))
load = get_load()
lcd.message('Avg Load %s' % (load))
#Temp and time
def screen3():
time = get_time();
lcd.message('%s\n' % (time))
lcd.message('Temp %s' % (temp))
#HD and SD usage
def screen4():
sd = get_sd()
lcd.message('SD Used %s\n' % (sd))
hd = get_hd()
lcd.message('HD Used %s' % (hd))
#Pause and clear
def screenPause(time):
sleep(time)
#In here to reduce lag
global temp
temp = str(get_temp(device));
lcd.clear()
###########################################################################################################
#Initialise
lcd.begin(16,2)
device = initialise_temp()
lcd.clear()
#Testing
#Main loop
while(1):
screen1()
screenPause(5)
screen2()
screenPause(5)
screen3()
screenPause(5)
screen4()
screenPause(5)
Ich weiß, dass ich wahrscheinlich havnt getan, Dinge, die die schreiben Weg, aber seine im ersten Versuch.
Mein Start-Skript in /etc/init.d Das ist das Skript:
#! /bin/sh
### BEGIN INIT INFO
# Provides: LCD looping
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: LCD daemon
# Description: This file should be used to construct scripts to be
# placed in /etc/init.d.
### END INIT INFO
# Author: Foo Bar <[email protected]>
#
# Please remove the "Author" lines above and replace them
# with your own name if you copy and modify this script.
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Loops the LCD screen through LCD.py"
NAME=startup.py
DAEMON=/home/pi/Programming/LCD/startup.py
DAEMON_ARGS=""
PIDFILE=/var/run/daemonLCD.pid
SCRIPTNAME=/etc/init.d/daemonLCD
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/daemonLCD ] && . /etc/default/daemonLCD
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
# Add code here, if necessary, that waits for the process to be ready
# to handle requests from services started subsequently which depend
# on this one. As a last resort, sleep for some time.
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:
Im glaube, ich habe etwas verpasst, als wenn ich daemonLCD starten, es sagt Befehl nicht gefunden.
Jede Eingabe wäre toll.
Dank
sind Sie sicher, dass das ist, was es sagt. es ist wahrscheinlicher
pi@raspberrypi /etc/init.d $ daemonLCD start-bash: daemonLCD: Befehl nicht gefunden
Mögliche Duplikate von : stackoverflow.com/questions/13718821/...
<FOO> :command not found
oder so... was ist foo?pi@raspberrypi /etc/init.d $ daemonLCD start-bash: daemonLCD: Befehl nicht gefunden
hostname -i
wäre die einfachere Lösung, um Ihre aktuelle ip -Mögliche Duplikate von : stackoverflow.com/questions/13718821/...
InformationsquelleAutor Joseph Roberts | 2012-12-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vorausgesetzt, Sie können verwalten möchten mehr als einen Dämon in die Zukunft, lassen Sie mich empfehlen Supervisord. Es ist viel einfacher als das schreiben und verwalten Sie Ihre eigenen init.d scripts.
Zum Beispiel, starten Sie Ihr Skript wäre so einfach wie auch diese in der conf:
Benutze ich ein init.d Skript hier erhältlich. Benennen Sie es um, supervisord und kopieren Sie Sie in Ihre /etc/init.d/dann ausführen:
Ich glaube, dass das init-script hat supervisord als root laufen, als Standard. Sie können es löschen, um " run as another user wenn Sie mögen. Ich bin nicht, wenn die Kinder führen Sie als root oder nicht, obwohl ich würde nicht davon ausgehen. Gehen Sie vor und überprüfen, aber wenn Sie nicht kleben Sie ein sudo vor den python-Befehl in der supervisord.conf, wo Sie rufen Sie das Skript.
Es, dass nicht ausgeführt wird, (oder wenn Sie wollen, supervisord zur Ausführung als nicht-root aber immer noch wollen, dass Ihr Skript als root ausführen) Sie können zulassen, dass für jemanden (oder eine Gruppe von Benutzern), um das python-Skript als root (obwohl Sie sollte machen ganz sicher, dass dieses Skript nicht bearbeitet werden kann, die von anderen Personen als root).
Bearbeiten Sie Ihre sudoers-Datei mit "sudo visudo" und fügen Sie die folgenden am Ende:
Dann stellen Sie sicher, Sie haben eine shebang am Anfang Ihrer python-Skript und ändern Sie den Befehl für das auslassen der python-call, ich.e:
Auch setzen Sie sich supervisord laufen auf boot mit update-rc.d? Wenn ja, soll ich meine supervisord Dateien aus usr/local/bin nach /etc/init.d? Nochmals vielen Dank
Lassen Sie mich wissen, wenn Sie die aktualisierte config/ root-Zeug funktioniert.
Ich habe es funktioniert. Dank sarwar
InformationsquelleAutor sarwar
Hier ist ein guter blog-Beitrag beschäftigt sich mit der Frage: Immer ein Python-script im hintergrund laufen (als Dienst) auf dem boot
InformationsquelleAutor Daniel F
Verwenden
daemontools
von der Hülse. Es ist viel einfacher als die anderen Antworten. Für den Anfang können Sie die Installation von daemon tools mit apt-get, so dass Sie nicht brauchen, zu kümmern, packte ein unbekanntes Skript von einem gist und erhalten Sie updates über debian, wie normal. daemontools kümmert sich auch um den Dienst neu zu starten, wenn es stirbt und sorgt für die Protokollierung. Es ist eine Beschreibung von daemontools und debian hier:http://blog.rtwilson.com/how-to-set-up-a-simple-service-to-run-in-the-background-on-a-linux-machine-using-daemontools/
Hülse s Seite aout
daemontools
:http://cr.yp.to/daemontools.html
InformationsquelleAutor dfc
Dies ist ein klassischer Fehler von neuen Unix - /Linux-Benutzer machen.
/etc/init.d
ist nicht in Ihrem Pfad das ist, warum Sie können nicht nur laufen daemonLCD. Versuchen Sie es mit dem vollen Pfad (/etc/init.d/daemonLCD start
) oder voranstellen von ./(./daemonLCD start
).Muss das Skript ausführbar sein, für die oben genannten arbeiten.
InformationsquelleAutor Martin
danke für den code oben. Ich nutze es, um herauszufinden, wie die Einrichtung eines daemon auf einem linux-Rechner.
Mit einigen Optimierungen konnte ich es ganz gut zu funktionieren.
Aber etwas verwirrt mich. Und das war die Prüfung, ob der Prozess ausgeführt wurde, durch die überprüfung der besteht aus der /var/run/myfile.pid
Ist das nur der PID - NICHT der Prozess, richtig?
Werfen Sie einen Blick in /lib/lsb/init-functions.status_of_proc
Ist nur der Umgang mit dem Erfolg oder Misserfolg der Zugriff auf die PID-Datei.
Nun, ich Baue diesen daemon zu gehen, auf ein kleines Gerät. Ich habe entdeckt, dass es mit BusyBox und ich habe keine init-functions 🙁
Aber ich habe pidof.
Also ich habe
und geprüft $LOGFILE und siehe da die zahlen sind anders.
Habe ich pstree -s -p auf beiden zahlen und
den pidof Anzahl spuckt eine sehr kurze Baum, so ist es für den root-level-Prozess
aber die $PIDFILE Anzahl erbricht sich Zweig nach Zweig, also ich glaube nicht, pstree können den Prozess gefunden.
Ja, die do_stop in Joseph Baldwin Roberts-code tötet beide Prozesse. Aber wenn der Prozess getötet werden, in einem anderen Weg, z.B. kill -9 12345, $PIDFILE ist immer noch da. So, der daemon wird fälschlicherweise glauben, der Prozess läuft bereits ein verweigern zu starten.
InformationsquelleAutor mycowan