Daemon in kombination mit watchdog

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Mazar
User
Beiträge: 8
Registriert: Donnerstag 15. März 2018, 15:23

Hallo zusammen,

ich habe ein Problem bei der Nutzung von watchdog in Verbindung mit einem daemon Prozess.

Ich habe ein Skript das sobald eine Datei in einem Ordner erstellt wird, diese Datei in einen neu erstellten Ordner verschiebt und dann ausdruckt. Dabei ist das erstellen des Ordners, verschieben, drucken usw. in einem zuvor erstellten Kindprozess. Bis hierhin funktioniert alles einwandfrei. Wenn ich aber noch die Daemon Klasse http://web.archive.org/web/201310171304 ... in_python/ hinzufüge, passiert außer das der Prozess erstellt wird nichts weiter.

Hier mal der Codeausschnitt:

Code: Alles auswählen

#!/usr/bin/python
import time
import datetime
import os
import shutil
import ConfigParser
import signal
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from daemon import Daemon

config = ConfigParser.RawConfigParser()
configFilePath = 'print.ini'
config.read(configFilePath)

def child():
	#print('\nA new child ',  os.getpid())
	
	tmp = datetime.datetime.now().strftime("%d.%m.%Y_%H:%M:%S")
	path = config.get('Path', 'Pickinglist')
	directory = './' + tmp + '/'

	move = 'mv *.pdf ' + path + tmp

	try:
		if not os.path.exists(directory):
	  		os.makedirs(directory)
	except OSError:
		print ('Error: Creating directory. ' + directory)


	os.system(move)
	os.chdir(directory)

	filename = os.listdir(path + tmp)
	order,printer = filename[0].split('_')
	printer = printer.replace('.pdf', '')
	
	while True:
		try:
			os.system('lp -d '+ printer + ' -o fit-to-page *.*')
		except OSError:
			print ('Error: Printing failed')
			continue
		break
	
	time.sleep(20)
	os.chdir('..')
	shutil.rmtree(directory)  

	os._exit(0)

def doit():
	event_handler = MyHandler()
	observer = Observer()
	observer.schedule(event_handler, path='.', recursive=False)
	observer.start()

	try:
	        while True:
            		time.sleep(1)
	except KeyboardInterrupt:
        	observer.stop()
    	observer.join()

 
class MyDaemon(Daemon):
	def run(self):
		doit()
		

class MyHandler(FileSystemEventHandler):
    def on_created(self, event):
       # print "Got it!"	
	
	if not event.is_directory:
	      	newpid = os.fork()
	     	if newpid == 0:
			child()


if __name__ == "__main__":

    daemon = MyDaemon('daemon-print.pid')
    if len(sys.argv) == 2:
                if 'start' == sys.argv[1]:
                        daemon.start()
                elif 'stop' == sys.argv[1]:
                        daemon.stop()
                elif 'restart' == sys.argv[1]:
                        daemon.restart()
		elif 'status' == sys.argv[1]:
                        daemon.status()
		elif 'print' == sys.argv[1]:
                        child()
                else:
                        print "Unknown command"
                        sys.exit(2)
                sys.exit(0)
    else:
                print "usage: %s start|stop|restart" % sys.argv[0]
                sys.exit(2)
    
Schonmal Danke für die Hilfe
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Mazar: gibt es Fehlermeldungen?

Zeile 22/24: Pfade setzt man mit os.path.join zusammen
Zeile 30: nach einem Exceptionhandling sollte das Programm weiterlaufen können. Ist hier nicht der Fall, weil gleich später das Programm wegen fehlendem Verzeichnis doch abstürzt. Hier: Fehlerhandling komplett löschen.
Zeile 33: keine externes Programm starten, sondern shutils.move benutzen.
Zeile 34: niemals chdir benutzen, das ändert einen globalen Zustand, was man normalerweise nicht möchte! Arbeite mit absoluten Pfaden.
Zeile 37: Dateinamen sind unsortiert, wenn es nur einen Dateinamen geben kann, teste das!
Zeile 38: es gibt os.path.splitext
Zeile 42: benutze subprocess statt os.system
Zeile 45: bei Fehler das System mit lp-Processen zu überfluten ist nicht sinnvoll
Zeile 45/46: dafür gibt es den else-Zweig
Zeile 49: siehe oben
Zeile 52: _-Funktionen sind nicht zum öffentlichen Verwenden gedacht.
Zeile 64, 80, ...: Einrückung kaputt
Mazar
User
Beiträge: 8
Registriert: Donnerstag 15. März 2018, 15:23

Hey Sirius3,

danke für die Tipps. Da das mein erstes Python Script ist sind solche Tipps Goldwert.

Ich habe das Script auch nun angepasst aber es passiert immer noch nichts, eine Fehlermeldung gab es auch noch nie. Wenn ich direkt die Funktion daemon.run() aufrufe funktioniert es auch, aber beim Aufruf von daemon.start() nicht. Der Unterschied dabei ist, dass start() den Prozess erst daemonized und dann die run Funktion aufruft. Ich bekomme so langsam das Gefühl, dass mein Vorhaben in Verbindung mit einem Daemon nciht funktioniert
Benutzeravatar
noisefloor
User
Beiträge: 3855
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

einen eigenen Daemon schreiben ist 2018 auch in vielen Fällen nicht sooo sinnvoll. Wenn du Unix nutzt, kannst du hier eine systemd Service Unit oder eine systemd Path Unit nutzen.

Oder wenn du einen Supervisor unabhängig von systemd brauchst supervisord.

Gruß, noisefloor
Mazar
User
Beiträge: 8
Registriert: Donnerstag 15. März 2018, 15:23

noisefloor hat geschrieben:Hallo,

einen eigenen Daemon schreiben ist 2018 auch in vielen Fällen nicht sooo sinnvoll. Wenn du Unix nutzt, kannst du hier eine systemd Service Unit oder eine systemd Path Unit nutzen.

Oder wenn du einen Supervisor unabhängig von systemd brauchst supervisord.

Gruß, noisefloor
Hi noisefloor,

Mit einem Service hat es nun funktioniert.

Vielen Dank für die Hilfe
Antworten