【问题标题】:python file throw strange error in bash script but runs perfectly by its ownpython 文件在 bash 脚本中抛出奇怪的错误,但可以自己完美运行
【发布时间】:2020-05-11 05:18:45
【问题描述】:

您好,我在树莓派上构建了一个 GPS 解决方案。

python 代码运行良好,直到我将所有内容都打包到一个 bash 脚本中……然后奇怪的事情发生了……

所以我有: 1. publish.py(此文件将 GPS 数据发布到 MQTT 主题) 2. listener.py(这个文件监听MQTT主题,用于测试目的) 3.job.sh(bash脚本运行一些命令publish.py文件) 4. crontab(我做了一个crontab,每10分钟运行一次来​​运行job.sh脚本)

发布.py

from gps import *
import time
from sense_hat import SenseHat
import json
import paho.mqtt.client as mqtt
import nacl.secret
import nacl.utils
import device

#initiate the device object
device = device.Device()

sense = SenseHat()
sense.clear()


timestamp = 0
latitude = 0
longitude = 0

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.subscribe("topic")

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("mqtt.eclipse.org", 1883, 60)

# put the symmetricKey into box
file = open("/home/pi/Project/symmetricKey", "rb")
symmetricKey = file.readline()
box = nacl.secret.SecretBox(symmetricKey)

def getPositionData(gps):
    nx = gpsd.next()
    if nx['class'] == 'TPV':
        global timestamp
        global latitude
        global longitude
        print("##############")
        timestamp = getattr(nx,'time', "Unknown")
        latitude = getattr(nx,'lat', "Unknown")
        longitude = getattr(nx,'lon', "Unknown")
        #print "##timestamp: ", timestamp, "##Your position: lon = ", str(longitude), ", lat = ", str(latitude)

    return timestamp, latitude, longitude

def getSenseHatData():
    pressure = sense.get_pressure()
    temp = sense.get_temperature()
    humidity = sense.get_humidity()
    #print "pressure: ", pressure, "temp: ", temp, "humidity: ", humidity

    return pressure, temp, humidity

def encrptyMessage(body):
    encrpted = box.encrypt(body)
    return encrpted

gpsd = gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)

def run():
    try:
        print ("Application started!")
        while True:
            gpsData = getPositionData(gpsd)
            senseHatData = getSenseHatData()
            dictionary = {
                "timestamp": gpsData[0],
                "latitude": gpsData[1],
                "longitude": gpsData[2],
                "pressure": senseHatData[0],
                "temp": senseHatData[1],
                "humidity": senseHatData[2]
            }
            body = json.dumps(dictionary)
            encrptedBody = encrptyMessage(body)

            print (dictionary)
            try:
                client.publish('topic', payload=encrptedBody)
            except:
                print("message is not successfully sent...")
            time.sleep(1.0)

    except (KeyboardInterrupt):
        running = False
        print ("Applications closed!")

    return body

run()

job.sh

#!/bin/bash

sudo systemctl start gpsd.socket & #this is to start GPS socket

sleep 5

python /home/pi/Project/publish.py & #this is to run my publish.py

sleep 10

sudo systemctl stop gpsd.socket & #this is to stop the socket service

crontab

*/10 * * * * bash /home/pi/job.sh

奇怪的是

当我直接运行publish.py时,一切正常......但是当我运行job.sh时,代码会抛出错误

Traceback (most recent call last):
  File "/home/pi/Project/publishTelemetry.py", line 123, in <module>
    run()
  File "/home/pi/Project/publishTelemetry.py", line 97, in run
    gpsData = getPositionData(gpsd)
  File "/home/pi/Project/publishTelemetry.py", line 45, in getPositionData
    nx = gpsd.next()
  File "/usr/lib/python2.7/dist-packages/gps/gps.py", line 287, in next
    return self.__next__()
  File "/usr/lib/python2.7/dist-packages/gps/gps.py", line 279, in __next__
    raise StopIteration

你知道如果 python 和 bash 有这种奇怪的行为吗???

感谢您的帮助!!!

【问题讨论】:

  • 我认为,您需要保持您的 publish.py 运行正常吗? (在您的代码中有一个 while True ),所以不要直接从 shell 脚本调用它,如 python file.py ,您必须使用类似屏幕的东西并将其分离,以便脚本继续在后台运行

标签: python bash cron raspberry-pi gpsd


【解决方案1】:

它完全按照应有的方式运行。您启动 gps 服务,然后异步启动您的脚本,10 秒后您停止 gps 服务。执行此操作后,读取循环会引发 StopIteration 以指示您无法获取新更新(因为服务已停止)。

假设这是预期的行为,您可以简单地捕获此异常并停止作业。

【讨论】:

  • 感谢@gerwin,我现在将 10 秒延长到 15 秒,因为有时服务器在检索任何数据之前就停止了。您的意思是在 gps.py 代码中捕获异常?还是我的 publish.py 代码?你能更具体一点吗?提前致谢
  • 如果我正确理解了您的问题,那么,是的:如果您想优雅地处理错误情况,只需将这一行:nx = gpsd.next() 换成 try-except StopIteration。然后在except子句中,退出程序。您的程序将以完全相同的方式运行,但您不会有异常日志,因为现在您已经处理了它。
  • 感谢@Gerwin!我认为根本问题是 GSP 传感器的行为不是很稳定,所以我必须将睡眠时间设置得更长才能检索足够的数据点……这真的让我发疯了,因为当我测试它时,有时代码有效,有时无效。 .
  • 作为一个建议:您也可以让 gps 服务一直运行,然后只将 Python 脚本放在 cron 中,并在获得所需数量的读数后停止。
猜你喜欢
  • 2016-08-05
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 2023-03-07
  • 2018-08-22
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
相关资源
最近更新 更多