【问题标题】:RPi python script fails to run from: /etc/rc.local, crontab, systemdRPi python 脚本无法从:/etc/rc.local、crontab、systemd 运行
【发布时间】:2018-05-23 18:40:38
【问题描述】:

我试图通过 systemctl 让这个 python 脚本从 /etc/rc.local、crontab @reboot 和 systemd 运行,但没有成功。

python 脚本在以用户 pi 身份登录时从命令行运行,并优雅地退出到后台而没有问题。以用户 pi 的身份在提示符下运行它也是如此:sh /etc/rc.local

任何指导将不胜感激,如下:

#!/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!\nReady 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 是否正常

# Default code located inside /etc/rc.local
# Print the IP address

    _IP=$(hostname -I) || true
    if [ "$_IP" ]; then
    printf "My IP address is %s\n" "$_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 的路径

# 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 的行为

     # 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

#!/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\n" "$_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 个好孩子积分才能上传图片。我将不得不发布成功完成本组最受赞赏的帮助。谢谢大家..照片网址和解决方案。

好的,这是我的语音识别项目照片的链接,由于我在 stackoverflow 上的新朋友的支持,该项目现在自动启动:

https://drive.google.com/file/d/19ribELmAnQFy4jfzi5D6I7fk91naS8J7/view?usp=drivesdk

【问题讨论】:

  • 您在问一个问题是否可以提出问题?如果您可以将其归结为MCVE,那很好,但从您的帖子看来,它可能相当广泛。
  • 好的,这里是具体细节。
  • 你能把这个脚本换成一个“hello world”类型的程序并尝试通过任何这样的方法运行它吗?让我们先排除脚本的问题。
  • -BlackVegetable 这是一个很好的起点。今晚会做,但我的 /home/pi/cigarbox.log 在我删除作业命令以将其置于后台时捕获脚本中的最后一条评论“即将连接”,例如&。所以,我认为它运行了,并且 MQTT 返回的内容搞砸了。有没有办法使用 /etc/rc.local 执行脚本,然后等待 10 秒钟,然后再将其置于后台,从而避开 rc.local 中的最后一行,它执行 exit 0 .....这可能阻止 MQTT 的返回?无论如何,今晚回到基础。谢谢!
  • 如果您可以在命令行中运行脚本,但不能以其他方式运行,这可能与您设置它的方式或文件权限或运行路径问题有关。您没有提供有关如何设置通过 /etc/rc.local 或 crontab 运行的信息。

标签: python json amazon-web-services raspberry-pi iot


【解决方案1】:

通过/etc/rc.local运行python脚本:

1) 使用sudo /etc/rc.local编辑文件;

2) 在exit 0之前的文件中添加以下内容:

(sleep 10;python /home/pi/Cigar-Box/CigarBox.py)&

括号允许您在后台运行多个命令。 sleep 10 会将脚本的运行延迟 10 秒,因为您的脚本所依赖的某些服务在启动 rc.local 时可能尚不可用。

您也可以使用 crontab @reboot 自动执行脚本。

使用 crontab:

1) 运行命令行sudo crontab -e;

2) 将命令添加到文件末尾:

@reboot /usr/bin/python /home/pi/Cigar-Box/CigarBox.py

【讨论】:

  • 我试图让这个 python 脚本从 /etc/rc.l 运行我试图让这个 python 脚本通过 systemctl 从 /etc/rc.local、crontab 和 systemd 运行,没有任何success.ocal、crontab @reboot 和 systemd 通过 systemctl 没有任何成功。我也考虑过使用延迟,但我认为脚本需要启动,然后在将其置于后台之前有一个延迟。你知道怎么做吗?同时,我将尝试 sleep 10 并回复您。谢谢。
  • 成功!!!你对问题的分析很到位。非常感谢您的指导和耐心。我最深切的感谢。请花点时间看看我的语音识别项目:drive.google.com/file/d/19ribELmAnQFy4jfzi5D6I7fk91naS8J7/…
  • 很高兴它对你有用。如果这个答案可以帮助您解决问题。请点赞。顺便说一句,这看起来很酷。
  • ...差点忘了,解决方案是在 /etc/rc.local 中使用 sleep 10 的每一个班轮:(sleep 10;python /home/pi/Cigar-Box/CigarBox.py )&
  • 点击这篇文章左上角的“向上”箭头或“勾号”。
猜你喜欢
  • 2016-03-06
  • 2016-06-05
  • 2015-01-06
  • 1970-01-01
  • 2016-06-20
  • 2017-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多