Python

python腳本沒有從crontab執行

  • March 25, 2020

這是論壇中提出的眾多問題之一。如果我從 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 行程式碼就足夠了)
  • 當你這樣做時,問題應該變得明顯,然後考慮我的其余建議

引用自:https://unix.stackexchange.com/questions/574836