RPi python 脚本无法从以下位置运行:/etc/rc.local、crontab、systemd [英] RPi python script fails to run from: /etc/rc.local, crontab, systemd
问题描述
我试图通过 systemctl 使这个 python 脚本从/etc/rc.local、crontab @reboot 和 systemd 运行,但没有成功.
I've tried to make this python script run from /etc/rc.local, crontab @reboot, and systemd via systemctl without any success.
python 脚本在以用户 pi 登录时从命令行运行,并正常退出到后台而没有问题.以用户 pi 的身份在提示符下运行它也是如此: sh/etc/rc.local
The python script runs from the command line while logged in as user pi and exits gracefully into the background without issue. The same goes for running it at the prompt as user pi with: sh /etc/rc.local
任何指导将不胜感激,如下:
Any guidance would be appreciated, as follows:
#!/usr/bin/python
#required libraries
import sys
import ssl
import paho.mqtt.client as mqtt
import json
from pprint import pprint
import Adafruit_CharLCD as LCD
from textwrap import fill
#Configuration
rootCAPath = "/home/pi/Cigar-Box/certs/rootCA.pem"
certFilePath = "/home/pi/Cigar-Box/certs/xxxxxxxxxx-certificate.pem.crt"
keyFilePath = "/home/pi/Cigar-Box/certs/xxxxxxxxxx-private.pem.key"
iotThing = "Zorua"
clientID = "Zorua"
#Device JSON initialization
device = {'state': {'reported': {'HP':100} } }
device['state']['reported']['color'] = {'r':0, 'g':0, 'b':0}
#Create LCD
lcd = LCD.Adafruit_CharLCDPlate()
#LCD wrapper
def set_lcd_color(R,G,B):
global lcd
device['state']['reported']['color']['r'] = R
device['state']['reported']['color']['g'] = G
device['state']['reported']['color']['b'] = B
lcd.set_color(R, G, B)
def set_lcd_message(message):
global lcd
device['state']['reported']['msg'] = message
lcd.clear()
#Word wrap to fit 16-char wide display and add capitalization
lcd_message = fill(message.capitalize(),16)
lcd.message(lcd_message)
# Initialize the LCD using the pins
set_lcd_message('Initializing...')
set_lcd_color(0, 0, 1)
#called while client tries to establish connection with the server
def on_connect(mqttc, obj, flags, rc):
print "Connecting..."
if rc==0:
print ("Subscriber Connection status code: "+str(rc)+" | Connectionstatus: successful")
#We only want to be notified about things we need to change to stay in sync with AWS
mqttc.subscribe("$aws/things/" + iotThing + "/shadow/update/delta", qos=1)
elif rc==1:
print ("Subscriber Connection status code: "+str(rc)+" | Connection status: Connection refused")
print ("Subscriber Connection status code: "+str(rc))
#called when a topic is successfully subscribed to
def on_subscribe(mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos)+"data"+str(obj))
set_lcd_color(0,1,0)
set_lcd_message('Connected!
Ready for input')
#Let AWS know about the current state of the plate so we can tell us what's out of sync
mqttc.publish("$aws/things/" + iotThing + "/shadow/update", json.dumps(device))
#called when a message is received by a topic
#Messages are formatted in JSON
#When working with /update, we might not find all keys all the time, so we need to handle that
def on_message(mqttc, obj, msg):
try:
data = json.loads(msg.payload)
update = data['state']
except:
return
#Look for a message in the update. If it's there, we need to update the display
if 'msg' in update.keys():
try:
set_lcd_message(update['msg'])
except:
print("Could not enact message from topic: "+msg.topic+" | QoS: "+str(msg.qos)+" | Data Received: "+str(msg.payload))
#Look to see if the status of R, G, or B has changed for the display
if 'color' in update.keys():
try: lcd_r = update['color']['r']
except: lcd_r = device['state']['reported']['color']['r']
try: lcd_g = update['color']['g']
except: lcd_g = device['state']['reported']['color']['g']
try: lcd_b = update['color']['b']
except: lcd_b = device['state']['reported']['color']['b']
set_lcd_color(lcd_r,
lcd_g,
lcd_b)
#Let AWS know we've updated the display
mqttc.publish("$aws/things/Zorua/shadow/update", json.dumps(device))
#creating a client with client-id=Zorua
mqttc = mqtt.Client(client_id=clientID)
mqttc.on_connect = on_connect
mqttc.on_reconnect = on_connect
mqttc.on_subscribe = on_subscribe
mqttc.on_message = on_message
#Configure network encryption and authentication options. Enables SSL/TLS support.
#adding client-side certificates and enabling tlsv1.2 support as required by aws-iot service
mqttc.tls_set(rootCAPath,
certfile=certFilePath,
keyfile=keyFilePath,
tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
#connecting to aws-account-specific-iot-endpoint
print ("About to connect")
mqttc.connect("lettersandnumbers.iot.us-west-2.amazonaws.com", port=8883) #AWS IoT service hostname and portno
#automatically handles reconnecting
mqttc.loop_forever()
位于/etc/rc.local 中的代码,然后是一个简单的重定向测试,以查看 rc.local 是否正常
The code located in /etc/rc.local followed by a simple redirect test to see if rc.local is behaving
# Default code located inside /etc/rc.local
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s
" "$_IP" > /home/pi/cigarbox.log
fi
exit 0
######################################################################
# After rebooting RPi = no output to log
pi@cigarbox:~ $ cat cigarbox.log
# Running /etc/rc.local from the command line
pi@cigarbox:~ $ sh /etc/rc.local
# After running /etc/rc.local locally = output to log
pi@cigarbox:~ $ cat cigarbox.log
My IP address is 192.168.0.21
这里是 pi 和 root 的路径
Here are the paths for pi and root
# Running as pi
pi@cigarbox:~ $ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
# Running s root
pi@cigarbox:~ $ su - root
Password:
root@cigarbox:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
不错.看起来 rc.local 正在运行
Nice. It looks like rc.local is behaving
# Cat and pipe of boot.log
root@cigarbox:~# cat /var/log/boot.log | grep rc.local
Starting /etc/rc.local Compatibility...
[ OK ] Started /etc/rc.local Compatibility.
但是,我过去曾尝试过此方法.根据建议,请参阅在括号中的 python 命令和路径下方注释的行.所以,脚本仍然不会用完/etc/rc.local
However, I've tried this in the past. See line commented out below the python command and path in parenthesis, per suggestion. So, the script still won't run out of /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# Print the IP address
#_IP=$(hostname -I) || true
#if [ "$_IP" ]; then
# printf "My IP address is %s
" "$_IP" > /home/pi/cigarbox.log
#fi
(python /home/pi/Cigar-Box/CigarBox.py)&
#/usr/bin/python /home/pi/Cigar-Box/CigarBox.py > /home/pi/cigarbox.log 2>&1 &
exit 0
嗯,看来我需要 10 个好孩子点才能上传图片.我将不得不发布本组最受赞赏的帮助的成功完成.谢谢大家..照片网址和要遵循的解决方案.
Hmm, it appears that I need 10 good boy points to upload images. I'll have to post the successful completion of this group's most appreciated help. Thank you all..photo URL and solution to follow.
好的,这是我的语音识别项目照片的链接,由于我的新朋友在 stackoverflow 的支持,该项目现在自动启动:
Okay, here's a link to a photo of my voice recognition project that now starts automatically because of the support from my new friends at stackoverflow:
https://drive.google.com/file/d/19ribELmAnQFy4jfzi5D6I7fk91naS8J7/view?usp=drivesdk
推荐答案
通过/etc/rc.local
运行python脚本:
1) 使用 sudo/etc/rc.local
编辑文件;
To run python script via /etc/rc.local
:
1) Edit the file using sudo /etc/rc.local
;
2) 在文件 exit 0
之前添加以下内容:
2) Add the following to the file right before exit 0
:
(sleep 10;python /home/pi/Cigar-Box/CigarBox.py)&
括号允许您在后台运行多个命令.sleep 10
会将脚本的运行延迟 10 秒,因为您的脚本所依赖的某些服务在启动 rc.local 时可能还不可用.
The parentheses allows your to run multiple commands in the background. The sleep 10
will delay the running of script by 10 seconds, as some of the services that your script depend on may not be available yet at the time of booting rc.local.
或者,您可以使用 crontab @reboot 来自动执行脚本.
Alternatively you can use crontab @reboot to automate the execution of your script.
1) 运行命令行 sudo crontab -e
;
2) 将命令添加到文件末尾:
2) add the command to the end of the file:
@reboot /usr/bin/python /home/pi/Cigar-Box/CigarBox.py
这篇关于RPi python 脚本无法从以下位置运行:/etc/rc.local、crontab、systemd的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!