-1

我的 Python 脚本退出时遇到了一些奇怪的行为,但没有任何错误消息。根据我的调试,它发生在 popen() 调用以将文件 scp 到服务器。

代码是(我不是原作者):

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

所以基于日志和输出数据。我相信在 SCP 期间出现了问题,因为 Python 脚本在记录“GPS log SCP complete”之前就崩溃了。有趣的是我在服务器端看到文件被完全复制。所以两个问题:

  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),否则无法确定,但很可能您没有看到任何内容,stderr因为没有任何内容被打印到stderr.

它几乎肯定不会崩溃,除非你有段错误、异常回溯或其他一些不相信的理由。您说它成功完成了所有工作,那么您认为它崩溃的原因是什么?

至于最后一条日志消息没有显示……logMessage如果您想要一个明确的答案,您必须向我们展示您的自定义代码,但我愿意永远不会成为您flushclose日志文件。

最后,您已经标记了您的问题multithreading,这很容易相关。同样,即使没有描述您是如何进行线程处理的,更不用说实际代码,我们只能猜测,但您可以,例如,在daemon=True线程中运行此代码,然后退出主线程。

于 2013-05-24T20:52:03.923 回答