-1

Python スクリプトがエラー メッセージなしで終了すると、奇妙な動作が発生します。私のデバッグに基づいて、ファイルをサーバーに scp するための popen() 呼び出しの周りで発生しています。

コードは次のとおりです (私は元の作成者ではありません)。

logMessage(LEVEL_INFO, "copyto is " + copyto)
pid = Popen(["scp", "-i", "/root/.ssh/id_rsa", "/usr/gpsw/gpslog" + self.node_addr, copyto], stdout=PIPE)
__s = pid.communicate()[0]
logMessage(LEVEL_INFO, "GPS log SCP complete")

デバッグしようとして、次のように拡張しました。

logMessage(LEVEL_INFO, "copyto is " + copyto)
pid = Popen(["scp", "-i", "/root/.ssh/id_rsa", "/usr/gpsw/gpslog" + self.node_addr, copyto], stdout=PIPE, stderr=PIPE)
out, err = pid.communicate()
if out:
    print "[" + self.node_addr + "] stdout of pid: " + str(out)
if err:
    print "[" + self.node_addr + "] stdout of pid: " + str(err)
print "[" + self.node_addr + "] returncode of pid: " + str(pid.returncode)
logMessage(LEVEL_INFO, "GPS log SCP complete")

これが私のコンソール出力です: (パターンは 5dda77、5dd9fa、5dda0d の繰り返しである必要があります。これは物理的なイベントに基づいています)

[5dda77] returncode of pid: 0
[5dd9fa] returncode of pid: 0
[5dda0d] returncode of pid: 0
[5dda77] returncode of pid: 0
[5dd9fa] returncode of pid: 0
[5dda0d] returncode of pid: 0
# (the script exited and I'm back at the prompt)

そして、ここに私のログ出力があります:

INFO copyto is root@192.168.20.1:/usr/scu/datafiles/gpslog5dda77
INFO GPS log SCP complete
INFO copyto is root@192.168.20.1:/usr/scu/datafiles/gpslog5dd9fa
INFO GPS log SCP complete
INFO copyto is root@192.168.20.1:/usr/scu/datafiles/gpslog5dda0d
INFO GPS log SCP complete
INFO copyto is root@192.168.20.1:/usr/scu/datafiles/gpslog5dda77
INFO GPS log SCP complete
INFO copyto is root@192.168.20.1:/usr/scu/datafiles/gpslog5dd9fa
INFO GPS log SCP complete
INFO copyto is root@192.168.20.1:/usr/scu/datafiles/gpslog5dda0d
INFO GPS log SCP complete
INFO copyto is root@192.168.20.1:/usr/scu/datafiles/gpslog5dda77

したがって、ログと出力データに基づいています。「GPS log SCP complete」をログに記録する前に Python スクリプトがクラッシュするため、SCP 中に何か問題が発生していると思われます。興味深いのは、サーバー側でファイルが完全にコピーされたことです。2つの質問:

  1. popen を間違って使用していますか?
  2. stderr にエラー メッセージが表示されないのはなぜですか?

ありがとう

編集: このスクリプトは決して終了しないでください。プロセスの「通常の終了」はありません。利用可能な GPS ノードからデータを取得するために、サーバーからのサービス要求を無期限に実行する必要があります。

主なループ コードは次のとおりです。

stop_flags = 0

... (API for server and GPS nodes to interact with)

def main():

    ... (System initialization)

    while stop_flags == 0:
        # listen for messages
        xmlrpcserver.handle_request()
        comm.poll()
    if stop_flags == STOP_FLAG_RESTART:
        # suppress Pylint warning for reimport of Popen,PIPE
        # pylint: disable-msg=W0404
        from subprocess import Popen, PIPE
        # use this instead of call to suppress output
        pid = Popen(["/etc/init.d/S999snap",
                    "restart"],
                    stdout=PIPE)
        __s = pid.communicate()[0]
    if stop_flags == STOP_FLAG_REBOOT:
        # suppress Pylint warning for reimport of Popen,PIPE
        # pylint: disable-msg=W0404
        from subprocess import Popen, PIPE
        # use this instead of call to suppress output
        pid = Popen(["reboot"],
                    stdout=PIPE)
        __s = pid.communicate()[0]

if __name__ == '__main__':
    main()
4

1 に答える 1

-1

あなたはPopenうまく使っています。

また、同じコマンドを別の方法でテストしない限り (たとえば、 を介して対話的に実行するなど) 確認することはできませんが、 に何も出力されていないため、 に何も表示さbashれない可能性が最も高いです。stderrstderr

セグメンテーション違反、例外のトレースバック、またはそうでないと信じるその他の理由がない限り、ほぼ確実にクラッシュしません。すべての作業を正常に終了したとおっしゃいましたが、なぜクラッシュしたと思いますか?

最後のログ メッセージが表示されないことについては…logMessage明確な回答が必要な場合は、カスタム コードを表示する必要がありますがflushcloseログ ファイルを表示しないようにします。

最後に、質問multithreadingにタグを付けました。これは簡単に関連する可能性があります。繰り返しになりますが、実際のコードはおろか、どのようにスレッド化を行っているかの説明さえなければ、推測するしかありませんが、たとえば、このコードをdaemon=Trueスレッドで実行してからメイン スレッドを終了することはできます。

于 2013-05-24T20:52:03.923 に答える