这是论坛中提出的众多问题之一。我有一个脚本,如果我从 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
答案1
我看没有异常处理在你的代码中。正确设计的应用程序应该具有异常处理和记录错误到一个文件。你说如果你删除部分代码,你的脚本就会运行,这意味着 cron 正在执行它,但如果发生错误,你就没有踪迹,调查也很困难。如果你有日志,也许你已经找出问题所在了。
我有时做的一件事是自动启动脚本GNU 屏幕会话,这样我就可以在启动后连接到屏幕控制台并查看正在运行的脚本。
查看您的代码,我发现您有一个本地 Mysql 实例。也许当你的脚本运行时Mysql还没有启动。可能就是这么简单。许多启动脚本错误地假设网络或其他一些服务在运行时始终可用。
更好的方法是创建自己的系统服务运行这个脚本。这并不难。当你这样做时,你可以建立依赖关系,例如您可以指定您的服务不应在 Mysql 服务等之前运行。
现在我建议采取以下步骤:
- 始终将 cron 作业的输出记录到文件中 - 您的脚本可能会输出错误,但您看不到它
- 通过添加异常处理来改进脚本(10 行代码就足够了)
- 当你这样做时,问题应该变得明显,然后思考我的其余建议