Python
python腳本沒有從crontab執行
這是論壇中提出的眾多問題之一。如果我從 linux 終端執行它,我有一個可以完美執行的腳本。但是,當我讓它在重新啟動時從 crontab 執行時,它不起作用。我編寫了一個簡單的腳本,該腳本與我的未執行的腳本從同一目錄執行,該腳本執行得非常好。該腳本對任何人都可以執行(chmod 777)。我認為問題出在sql程式碼的某個地方。我對此很感興趣,但找不到我的腳本的問題,這就是我“重新”問這個問題的原因。提前致謝!
ps:這個腳本遠非完美,只是一個需要優化的執行腳本
crontab 的程式碼:
@reboot sudo /usr/bin/python /home/pi/AansturingLedGesturctureerd.py
腳本程式碼:
#! /usr/bin/env python import RPi.GPIO as GPIO import sys import time import MySQLdb import datetime # RGB LED pinnen configureren. pinRood = 27 pinGroen = 22 pinBlauw = 17 # GPIO setup. GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) # Zet de GPIO pinnen als uitgang. GPIO.setup(pinRood, GPIO.OUT) GPIO.setup(pinGroen, GPIO.OUT) GPIO.setup(pinBlauw, GPIO.OUT) # Gebruik PWM op de pinnen. ROOD = GPIO.PWM(pinRood, 1000) GROEN = GPIO.PWM(pinGroen, 1000) BLAUW = GPIO.PWM(pinBlauw, 1000) ROOD.start(0) GROEN.start(0) BLAUW.start(0) #defienieren functies def dataUitlezenFile(): global dataAansturingLedGesplitst bestandAansturingLed = open("/var/www/html/v1.11_layout_aanpassen_login_form_3/extraBestanden/ledAansturing.txt", "r") dataAansturingLed = bestandAansturingLed.read() dataAansturingLedGesplitst = dataAansturingLed.split() #print(dataAansturingLedGesplitst[3]) def dataWissen(): dataWissenFile = open("/var/www/html/v1.11_layout_aanpassen_login_form_3/extraBestanden/ledAansturing.txt", "w") dataWissenFile.truncate(0) dataWissenFile.write("0 0 0 niks") dataWissenFile.close() def dataUitlezenSQL(dataAansturingLedGesplitst): global speelTijdActief global ingesteldeTijd global tijdDatabase global tijdVerlopen #connecteer met de database connection = MySQLdb.connect (host = "localhost", user = "******", passwd = "****", db = "test") cursor = connection.cursor() sqlQuerry = "SELECT stopTijd FROM gespeeldetijd WHERE naam = '" + "Emile" + "' ORDER BY ID DESC LIMIT 1" rows_count = cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op row = cursor.fetchone() if (rows_count >= 1): tijdDatabase = row[0] #print("true") else: tijdDatabase = datetime.datetime.strptime("1685-06-29 08:15:27", '%Y-%m-%d %H:%M:%S') tijdNu = datetime.datetime.now() #haal de huidige tijd op #print(tijdNu) #print(tijdDatabase) #print(tijdNu) tijdNu = datetime.datetime.now() #haal de huidige tijd op cursor = connection.cursor() #ophalen tijd om de relais en de hdmi connector aan te zetten of te onderbreken sqlQuerry = "SELECT tijd FROM extra WHERE functie = 'uitschakelTijd'" cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op row = cursor.fetchone() uitschakeltijd = row[0] uitschakeltijdString = str(uitschakeltijd) h, m, s = uitschakeltijdString.split(':') uitschakeltijdSecondes = int(h) * 3600 + int(m) * 60 + int(s) uitschakeltijdSecondesNegate = uitschakeltijdSecondes * -1 cursor = connection.cursor() #uitschakeltijd ophalen sqlQuerry = "SELECT stopTijd FROM gespeeldetijd WHERE naam = 'Emile' ORDER BY ID DESC LIMIT 1" cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op row = cursor.fetchone() row_count = cursor.rowcount if row_count == 0: tijdDatabaseLaatsteTijd = datetime.datetime.strptime("1685-06-29 08:15:27", '%Y-%m-%d %H:%M:%S') else: tijdDatabaseLaatsteTijd = row[0] if (tijdDatabaseLaatsteTijd < tijdNu): # controleer of de eindtijd is bereikt #print("eindtijd bereikt") tijdDatabaseCorrecteNotatie = datetime.datetime.strptime(str(tijdDatabaseLaatsteTijd), '%Y-%m-%d %H:%M:%S') #vorm de tijd om van de database naar een juistee notatie huidigeTijdCorrecteNotatie = datetime.datetime.now() # correcte notatie van de huidige tijd overigeTijdSeconden = ((tijdDatabaseCorrecteNotatie-huidigeTijdCorrecteNotatie).total_seconds()) #berekenen van het overige aantal seconden #print(overigeTijdSeconden) #print(uitschakeltijdSecondesNegate) if (overigeTijdSeconden <= uitschakeltijdSecondesNegate): #controleer of de eindtijd al meer als 5 minuten is verlopen tijdVerlopen = "verlopen" #print("veel meer seconden verlopen!") else: tijdVerlopen = "uitschakeltijd" #print(tijdVerlopen) #print("zit nog in de fase") else: tijdVerlopen = "verlopen" #print(tijdVerlopen) if(tijdVerlopen == "verlopen"): if (tijdDatabase > tijdNu): # controleer of er een tijd lopende is speelTijdActief = "actief" cursor = connection.cursor() sqlQuerry = "SELECT tijd FROM gespeeldetijd WHERE naam = '" + "Emile" + "' ORDER BY ID DESC LIMIT 1" rows_count = cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op #print(rows_count) row = cursor.fetchone() genre_id_val = cursor.fetchone() if (rows_count >= 1): ingesteldeTijd = row[0] #print("true") else: ingesteldeTijd = "00:00:00" else: cursor = connection.cursor() sqlQuerry = "SELECT stopTijd FROM gespeeldetijd WHERE naam = '" + "Thomas" + "' ORDER BY ID DESC LIMIT 1" rows_count = cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op row = cursor.fetchone() genre_id_val = cursor.fetchone() #print(rows_count) if (rows_count >= 1): tijdDatabase = row[0] #print(" 3") else: tijdDatabase = datetime.datetime.strptime("1685-06-29 08:15:27", '%Y-%m-%d %H:%M:%S') #print(" 4") #print(tijdDatabase) tijdNu = datetime.datetime.now() #haal de huidige tijd op #print(tijdNu) #print(tijdDatabase) #print(tijdNu) cursor = connection.cursor() #ophalen tijd om de relais en de hdmi connector aan te zetten of te onderbreken sqlQuerry = "SELECT tijd FROM extra WHERE functie = 'uitschakelTijd'" cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op row = cursor.fetchone() uitschakeltijd = row[0] uitschakeltijdString = str(uitschakeltijd) h, m, s = uitschakeltijdString.split(':') uitschakeltijdSecondes = int(h) * 3600 + int(m) * 60 + int(s) uitschakeltijdSecondesNegate = uitschakeltijdSecondes * -1 cursor = connection.cursor() #uitschakeltijd ophalen sqlQuerry = "SELECT stopTijd FROM gespeeldetijd WHERE naam = '" + "Thomas" + "' ORDER BY ID DESC LIMIT 1" cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op row = cursor.fetchone() if (row == "none"): tijdDatabaseLaatsteTijd = row[0] else: tijdDatabaseLaatsteTijd = datetime.datetime.strptime("1685-06-29 08:15:27", '%Y-%m-%d %H:%M:%S') if (tijdDatabaseLaatsteTijd < tijdNu): # controleer of de eindtijd is bereikt #print("tijd is verlopen, nu gaat andere tijd in") tijdDatabaseCorrecteNotatie = datetime.datetime.strptime(str(tijdDatabaseLaatsteTijd), '%Y-%m-%d %H:%M:%S') #vorm de tijd om van de database naar een juistee notatie huidigeTijdCorrecteNotatie = datetime.datetime.now() # correcte notatie van de huidige tijd overigeTijdSeconden = ((tijdDatabaseCorrecteNotatie-huidigeTijdCorrecteNotatie).total_seconds()) #berekenen van het overige aantal seconden #print(tijdDatabaseCorrecteNotatie) #print(huidigeTijdCorrecteNotatie) #print(overigeTijdSeconden) if (overigeTijdSeconden >= uitschakeltijdSecondesNegate): #controleer of de eindtijd al meer als 5 minuten is verlopen tijdVerlopen = "uitschakeltijd" #print(tijdVerlopen) else: tijdVerlopen = "verlopen" #print(tijdVerlopen) else: tijdVerlopen = "verlopen" #print(tijdVerlopen) tijdNu = datetime.datetime.now() #haal de huidige tijd op if (tijdDatabase > tijdNu): # controleer of er een tijd lopende is speelTijdActief = "actief" cursor = connection.cursor() sqlQuerry = "SELECT tijd FROM gespeeldetijd WHERE naam = '" + "Thomas" + "' ORDER BY ID DESC LIMIT 1" rows_count = cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op row = cursor.fetchone() genre_id_val = cursor.fetchone() if (rows_count >= 1): ingesteldeTijd = row[0] else: ingesteldeTijd = "00:00:00" else: ingesteldeTijd = "00:00:00" speelTijdActief = "nietActief" cursor.close() connection.close() def statusSetup(): global setupStatus #connecteer met de database connection = MySQLdb.connect (host = "localhost", user = "root", passwd = "*****", db = "test") cursor = connection.cursor() sqlQuerry = "SELECT status FROM extra WHERE functie = 'setup'" cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op row = cursor.fetchone() dataSetup = row[0] if (dataSetup == "notCompleted"): # hier gaan we de variabele zetten die zal bepalen welke led aangat statusSetup = 'setUp' else: overbrugStatus = 'setUpCompleted' cursor.close() connection.close() def statusOverbrug(): global overbrugStatus #connecteer met de database connection = MySQLdb.connect (host = "localhost", user = "root", passwd = "****", db = "test") cursor = connection.cursor() sqlQuerry = "SELECT status FROM extra WHERE functie = 'overbrug'" cursor.execute (sqlQuerry) #haal de laatst gespeelde tijd op row = cursor.fetchone() dataSetup = row[0] if (dataSetup == "ingeschakeld"): # hier gaan we de variabele zetten die zal bepalen welke led aangat overbrugStatus = 'overbrug' else: overbrugStatus = 'nietOverbrugd' cursor.close() connection.close() while True: while True: #nakijken welke data we hebben #bekijk file die in de data zit dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() if (statusSetup == 'setUp' ): while True: # converteer de waarde 255 tot max 100 voor PWM. roodwaarde = 0 groenwaarde = 0 blauwwaarde = 100 ROOD.ChangeDutyCycle(roodwaarde) GROEN.ChangeDutyCycle(groenwaarde) BLAUW.ChangeDutyCycle(blauwwaarde) dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() if (dataAansturingLedGesplitst[3] != 'setUp'): break if (speelTijdActief == "actief"): while True: tijdNu = datetime.datetime.now() #haal de huidige tijd op h, m, s = ingesteldeTijd.split(':') ingesteldeTijdSeconden = int(h) * 3600 + int(m) * 60 + int(s) if(tijdNu <= tijdDatabase): overigeTijd = tijdDatabase - tijdNu testTijd = str(overigeTijd) gesplitsteTijd = testTijd.split('.') tijdNodig = gesplitsteTijd[0] h, m, s = tijdNodig.split(':') overigeTijdSeconden = int(h) * 3600 + int(m) * 60 + int(s) else: overigeTijdSeconden = 0 if(ingesteldeTijdSeconden == 0): percentageOver = -1 else: percentageOver = float(overigeTijdSeconden)/float(ingesteldeTijdSeconden)*float(100) print(percentageOver) if (percentageOver > 50.0): roodwaarde = 0 groenwaarde = 100 blauwwaarde = 0 ROOD.ChangeDutyCycle(roodwaarde) GROEN.ChangeDutyCycle(groenwaarde) BLAUW.ChangeDutyCycle(blauwwaarde) if (percentageOver <= 50.0 and percentageOver >= 30.0): roodwaarde = 100 groenwaarde = 100 blauwwaarde = 0 ROOD.ChangeDutyCycle(roodwaarde) GROEN.ChangeDutyCycle(groenwaarde) BLAUW.ChangeDutyCycle(blauwwaarde) if (percentageOver < 30.0 and percentageOver > 10.0): roodwaarde = 100 groenwaarde = 50 blauwwaarde = 0 ROOD.ChangeDutyCycle(roodwaarde) GROEN.ChangeDutyCycle(groenwaarde) BLAUW.ChangeDutyCycle(blauwwaarde) if (percentageOver <= 10.0 and percentageOver > 0.0): roodwaarde = 100 groenwaarde = 0 blauwwaarde = 0 ROOD.ChangeDutyCycle(roodwaarde) GROEN.ChangeDutyCycle(groenwaarde) BLAUW.ChangeDutyCycle(blauwwaarde) dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() if (speelTijdActief == "nietActief" or tijdVerlopen == "uitschakeltijd"): break if (overbrugStatus == 'overbrug'): i = 0 while (i <= 255): roodwaarde = 255 groenwaarde = i blauwwaarde = 0 ROOD.ChangeDutyCycle(roodwaarde*100/255) GROEN.ChangeDutyCycle(groenwaarde*100/255) BLAUW.ChangeDutyCycle(blauwwaarde*100/255) i = i + 1 dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() if (overbrugStatus != 'overbrug'): break i = 255 while (i >= 0): roodwaarde = i groenwaarde = 255 blauwwaarde = 0 ROOD.ChangeDutyCycle(roodwaarde*100/255) GROEN.ChangeDutyCycle(groenwaarde*100/255) BLAUW.ChangeDutyCycle(blauwwaarde*100/255) i = i - 1 dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() if (overbrugStatus != 'overbrug'): break i = 0 while (i <= 255): roodwaarde = 0 groenwaarde = 255 blauwwaarde = i ROOD.ChangeDutyCycle(roodwaarde*100/255) GROEN.ChangeDutyCycle(groenwaarde*100/255) BLAUW.ChangeDutyCycle(blauwwaarde*100/255) i = i + 1 dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() if (overbrugStatus != 'overbrug'): break i = 255 while (i >= 0): roodwaarde = 0 groenwaarde = i blauwwaarde = 255 ROOD.ChangeDutyCycle(roodwaarde*100/255) GROEN.ChangeDutyCycle(groenwaarde*100/255) BLAUW.ChangeDutyCycle(blauwwaarde*100/255) i = i - 1 dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() if (overbrugStatus != 'overbrug'): break if (dataAansturingLedGesplitst[3] == 'niks' and not statusSetup == 'setUp' and not speelTijdActief == "actief" and not overbrugStatus == 'overbrug'): while True: #print('uitvoeren') i = 212 j = 33 while (i >= 33): while (j <= 212): if (i >= 33): groenwaarde = i else: groenwaarde = 33 if (j <= 183): roodwaarde = j else: roodwaarde = 183 blauwwaarde = 255 i = i - 1 j = j + 1 ROOD.ChangeDutyCycle(roodwaarde*100/255) GROEN.ChangeDutyCycle(groenwaarde*100/255) BLAUW.ChangeDutyCycle(blauwwaarde*100/255) time.sleep(0.01) dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() if (not dataAansturingLedGesplitst[3] == 'niks' or statusSetup == 'setUp' or speelTijdActief == "actief"): break dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() time.sleep(1) dataUitlezenFile() dataUitlezenSQL(dataAansturingLedGesplitst) statusSetup() statusOverbrug() if (not dataAansturingLedGesplitst[3] == 'niks' or statusSetup == 'setUp' or speelTijdActief == "actief" or overbrugStatus == 'overbrug'): break if (not dataAansturingLedGesplitst[3] == 'niks' or statusSetup == 'setUp' or speelTijdActief == "actief"): break
我在您的程式碼中沒有看到異常處理。一個設計合理的應用程序應該有異常處理並將錯誤記錄到文件中。您說如果您刪除部分程式碼,您的腳本就會執行,這意味著 cron 正在執行它,但是如果發生錯誤,您將無法追踪,並且很難進行調查。如果您有日誌,也許您已經發現了問題所在。
我有時會做的一件事是在GNU 螢幕會話中自動啟動腳本,這樣我就可以在啟動後附加到螢幕控制台並查看正在執行的腳本。
查看您的程式碼,我看到您有一個本地 Mysql 實例。當您的腳本執行時,可能尚未啟動 Mysql。可能就這麼簡單。許多啟動腳本錯誤地假設網路或其他服務在執行時始終可用。
更好的方法是創建自己的systemd 服務來執行此腳本。這並不難。當你這樣做時,你可以建立依賴關係,例如你可以指定你的服務不應該在 Mysql 服務之前執行等。
現在我建議以下步驟:
- 總是將你的 cron 作業的輸出記錄到一個文件中——你的腳本可能會吐出一個錯誤,但你看不到它
- 通過添加異常處理來改進你的腳本(10 行程式碼就足夠了)
- 當你這樣做時,問題應該變得明顯,然後考慮我的其余建議