简体   繁体   English

运行shell时如何禁用stdout缓冲区

[英]How to disable stdout buffer when running shell

I am using Python to call a Shell script with我正在使用 Python 调用 Shell 脚本

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

Then I run然后我跑

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

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 的控制台输出不是实时的,看起来 stdout 有一个缓冲区,当 stdout 缓冲区已满时,就会打印输出。

I would ask how to disable the shell stdout buffer in my script a.sh我会问如何在我的脚本 a.sh 中禁用 shell stdout 缓冲区

Thanks!谢谢!

The buffering in question would largely be a problem on the script's side, not the Python side;有问题的缓冲主要是脚本方面的问题,而不是 Python 方面的问题; while Python would buffer the reads, it wouldn't block unless the buffer was emptied and there was nothing available to read.虽然 Python 会缓冲读取,但它不会阻塞,除非缓冲区被清空并且没有任何可读取的内容。

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).在某些情况下(程序不会在内部调整自己的缓冲),将stdbuf -oL (或-o0表示完全无缓冲,但行缓冲应该覆盖您,因为您也按行读取)到您的命令应该会有所帮助。

If you're seeing this behavior only by looking at Python's output, be aware that Python itself can buffer output as well.如果您只是通过查看 Python 的输出看到这种行为,请注意 Python 本身也可以缓冲输出。 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.您可以通过在运行 Python 时传递-u或在运行它之前设置环境变量PYTHONUNBUFFERED=1来禁用此功能,或者在脚本中,您可以在任何写入(直接或隐式通过sys.stdout.flush()后手动调用sys.stdout.flush() print ) 到标准输出。 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.在现代 Python 中, print接受一个参数以在打印后强制flush ,但由于您使用的是 Python 2.x,这不是一个选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM