0

私はラズベリーを搭載したラズベリーパイを持っており、常に実行する必要のあるPythonスクリプトを作成しました。問題は、1時間ほど実行した後、スクリプトが突然停止し、Pythonプロセスがシャットダウンすることです。理由はわかりません。Linuxは初めてなので、デバッグ方法などもわかりません。whileループ中に、使用されているすべてのオブジェクトを解放して再初期化するため、メモリの問題ではないと思います。問題が何であるかを知るにはどうすればよいですか、または少なくともプログラムが停止したら自動的に再起動しますか?

これはコードです:

import time
import sys
import ftputil
import pygame
import pygame.camera
import logging

pygame.camera.init()
#pygame.camera.list_camera() #Camera detected or not
cam = pygame.camera.Camera("/dev/video0",(640,480))
count = 5
logging.basicConfig(filename='log.log', level=logging.INFO)
logging.info(str(time.time())+" : Script was started")

while True:
        cam.start()
        img = cam.get_image()
        pygame.image.save(img,"current.jpeg")
        cam.stop()
        host = ftputil.FTPHost(**)
        host.upload("./current.jpeg", "/domains/*/public_html/webcam.jpg", mode='b')
        host.close()
        if not count:
                host = ftputil.FTPHost(**)
                filename = str(time.time()) + ".jpg"
                host.upload("./current.jpeg", "/webcamarchive/"+filename, mode='b')
                host.close()
                count = 10
                logging.info(str(time.time())+": Still running")
        count -= 1
        time.sleep(3)

sshからスクリプトを実行します。しかし、コンピュータの起動時にも起動させたいのですが、どうすればよいですか?

4

1 に答える 1

2

通常のログインセッションで継続的に実行できるようになるまで、コンピュータが起動するたびに実行することを心配する必要はありません。

sshコンピューターを起動して開始する場合は、sshセッションを開いたままにして、印刷内容を確認してください。なんらかの理由でそれができない場合は、たとえば、python foo.py >foo.out 2>foo.errだけでなく、次のようにして出力をキャプチャしますpython.py。いずれにせよ、停止したことを知るだけでなく、停止した理由を確認できます。

またlog.log、コードで明示的に作成したファイルと、syslog(/var/log/syslogほとんどのLinuxディストリビューションではデフォルト)を調べて、そこに関連するものがあるかどうかを確認する必要があります。

また、 「sshからスクリプトを実行する」方法を正確に教えてください。バックグラウンドでバックグラウンドを設定し&たり、コマンドとして送信したりする場合は、ssh上記の手順を変更する必要があります。(ただし、変更されたバージョンを待つ必要はありません。これを1回だけssh、通常のログインスクリプトに入れて、バックグラウンドなしで実行し、実行したままにします。)

あなたがこれまでに私たちに提供した情報だけでは、何が起こっているのかを正確に知ることは不可能です。しかし、私の最初の推測では、未処理の例外が発生していると思います。これは、次のような例外トレースバックとして表示されます。

Traceback (most recent call last):
  File "exc.py", line 7, in <module>
    foo()
  File "exc.py", line 5, in foo
    print(1/x)
ZeroDivisionError: integer division or modulo by zero

修正はそれを処理することです。最も簡単な修正は次のようなものです。

while True:
    try:
        cam.start()
        img = cam.get_image()
        pygame.image.save(img,"current.jpeg")
        cam.stop()
        host = ftputil.FTPHost(**)
        host.upload("./current.jpeg", "/domains/*/public_html/webcam.jpg", mode='b')
        host.close()
        if !count:
                host = ftputil.FTPHost(**)
                filename = str(time.time()) + ".jpg"
                host.upload("./current.jpeg", "/webcamarchive/"+filename, mode='b')
                host.close()
                count = 10
                logging.info(str(time.time())+": Still running")
        count -= 1
    except Exception as e:
        logging.error('Caught exception: ' + str(e))
    time.sleep(3)

ただし、発生する可能性のある各種類の例外を確認するか、実際に発生する例外を確認し、適切なエラー処理とロギングを各場所に配置し、これを最後に使用する方がよいでしょう。溝のフォールバック。

また、手動呼び出しの代わりに、実際にはwith句を使用する必要があります。closeたとえば、host.upload()レイズした場合、host.close()は呼び出されません。したがって、これの代わりに:

host = ftputil.FTPHost(**)
host.upload("./current.jpeg", "/domains/*/public_html/webcam.jpg", mode='b')
host.close()

これを行う:

with contextlib.closing(ftputil.FTPHost(**)) as host:
    host.upload("./current.jpeg", "/domains/*/public_html/webcam.jpg", mode='b')

(多くのタイプはclosing、すでに本質的にコンテキストマネージャーであるため、を必要としません。最初にそれを試してください。ただし、またはがftputil.FTPHostないことについてエラーが発生した__enter__場合__exit__は、これが対処方法です。)

于 2012-12-21T23:31:41.640 に答える