运行shell时如何禁用stdout缓冲区 [英] How to disable stdout buffer when running shell

查看:92
本文介绍了运行shell时如何禁用stdout缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Python调用

I am using Python to call a Shell script with

def run_command(cmd):
    print "Start to run: " + cmd
    run = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while True:
        line = run.stdout.readline().decode()[:-1]
        if line == '' and run.poll() is not None:
            break
        print line # print the log from shell
    recode = run.returncode
    if recode != 0:
        raise Exception("Error occurs!")

    print "End to run: " + cmd

然后我跑

run_command("sh /home/tome/a.sh")

我注意到a.sh的控制台输出不是实时的,看起来好像有一个用于stdout的缓冲区,当stdout缓冲区已满时,就会输出输出.

I notice the console output from a.sh is not in real time, looks like that there is a buffer for the stdout and when the stdout buffer is full, then the output is printed out.

我会问如何在我的脚本a.sh中禁用shell stdout缓冲区

I would ask how to disable the shell stdout buffer in my script a.sh

谢谢!

推荐答案

有问题的缓冲在很大程度上是脚本方面的问题,而不是Python方面的问题;尽管Python会缓冲读取的内容,但除非清空缓冲区并且没有可用的读取内容,否则它不会阻塞.

The buffering in question would largely be a problem on the script's side, not the Python side; while Python would buffer the reads, it wouldn't block unless the buffer was emptied and there was nothing available to read.

实际上,您需要在脚本本身中禁用缓冲.添加 stdbuf -oL (或 -o0表示完全没有缓冲,但是行缓冲应该覆盖您,因为您也可以逐行阅读),在某些情况下(程序内部没有调整自己的缓冲),命令应该有所帮助.

So really, you need to disable buffering in the script itself. Adding stdbuf -oL (or -o0 for completely unbuffered, but line buffering should cover you since you read by line as well) to your commands should help in some cases (where the programs don't adjust their own buffering internally).

如果仅通过查看Python的输出即可看到此行为,请注意Python本身也可以缓冲输出.您可以通过在运行Python时传递 -u 或在运行它之前设置环境变量 PYTHONUNBUFFERED = 1 来禁用此功能,或者从脚本中手动调用 print 隐式)后,> sys.stdout.flush().在现代Python上, print 接受一个参数以在打印后强制进行 flush ,但是由于您使用的是Python 2.x,因此这不是一个选择.

If you're seeing this behavior only by looking at Python's output, be aware that Python itself can buffer output as well. You can disable this by passing -u when running Python, or setting the environment variable PYTHONUNBUFFERED=1 before running it, or from within a script, you can manually call sys.stdout.flush() after any writes (direct, or implicit via print) to stdout. On modern Python, print takes an argument to force a flush after printing, but since you're on Python 2.x, that's not an option.

这篇关于运行shell时如何禁用stdout缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆