Python捕获Popen输出

时间:2013-05-24 20:44:11

标签: python multithreading popen scp stderr

我的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中没有看到任何错误消息?
  3. 谢谢

    修改 此脚本永远不会退出。该过程没有“正常退出”。它应无限期地运行,以服务于来自服务器的请求,以从可用的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()
    

1 个答案:

答案 0 :(得分:-1)

您正在使用Popen

而且,虽然除非你以其他方式自己测试相同的命令(例如,只是通过bash以交互方式运行它们),否则无法确定,但很可能你没有在{{stderr中看到任何内容。 1}}因为没有任何内容打印到stderr

几乎可以肯定没有崩溃,除非你有一个段错误,异常追溯或其他一些原因让人不相信。你说它成功地完成了所有的工作,那么是什么让你认为它崩溃了?

至于上次显示的日志消息...如果您想要一个明确的答案,则必须向我们展示您的自定义logMessage代码,但我愿意永远不会flush或{{ 1}}日志文件。

最后,您已标记了您的问题close,这很容易相关。同样,甚至没有描述你如何进行线程,更不用说实际的代码,我们除了猜测之外什么都做不了,但你可以,例如,在multithreading线程中运行这个代码,然后退出主线。