【问题标题】:Execute Shell-Command over python using subprocess使用子进程在 python 上执行 Shell-Command
【发布时间】:2016-05-07 05:32:07
【问题描述】:

当我在 Python-Skript 上执行命令(当为真时;执行日期;睡眠 1;完成)时,什么都没有显示,也没有日志记录。

import logging
import sys
import subprocess as SP


logger = logging.getLogger('logging')
logger.setLevel(logging.INFO)

if not logger.handlers:
    log_handler = logging.FileHandler('test_logging.log')
    formatter = logging.Formatter('%(asctime)s %(message)s')
    log_handler.setFormatter(formatter)
    logger.addHandler(log_handler)
    log_handler.setLevel(logging.INFO)

command = 'while true; do date; sleep 1; done'
p = SP.Popen(command, shell=True, stdout=SP.PIPE, stderr=SP.PIPE)
print p.stdout.readlines()

for line in p.stdout.readlines():
    logger.info(line)
    print line

【问题讨论】:

    标签: python logging subprocess


    【解决方案1】:

    这对我有用(在 Python 2.6.6 上)

    import subprocess as SP
    command = 'while true; do date; sleep 1; done'
    p = SP.Popen(command, shell=True, bufsize=1, stdout=SP.PIPE, stderr=SP.PIPE)
    while True:
        print p.stdout.readline()
    

    bufsize=1 不是必需的,但它打开了行缓冲,这应该会提高一点效率。

    【讨论】:

    • @eugeney:那么最好使用其中一种方便的函数,例如subprocess.check_output,而不是直接调用subprocess.Popen
    【解决方案2】:

    p.stdout.readlines() 尝试读取列表中命令输出的所有行,由于该命令是一个无限循环,因此永远不会完成:'while true; do date; sleep 1; done'

    如果您使用的是 Python 2,迭代输出行的一种方法可能是:

    for line in iter(p.stdout.readline, b''):
        print line.rstrip()
    

    在 Python 3 中,您可以简单地遍历 p.stdout 文件对象。

    【讨论】:

    • 如果在 Ubuntu 14.04 机器上使用 Python 2(如打印语法所暗示的那样),这只会挂起。如果我使用 Python 3,它就可以工作。我对 subprocess.PIPE 的内部了解不足,无法推测原因。
    • @J Richard:确实,迭代文件对象在 Python 2 中似乎不起作用。我已经用工作版本更新了帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多