Python subprocess: 为什么stdin=PIPE会改变某些命令的输出?

0 投票
1 回答
1242 浏览
提问于 2025-04-17 16:57

有些交互式命令在输入通过管道传递时,输出的结果会有所不同。这是为什么呢?

下面我用subprocess.Popen测试了三条不同的命令,分别在有和没有输入管道的情况下进行测试。

 
代码:

import subprocess, time


def run_command(command, enable_input):
    print 'command="{}", enable_input={}:'.format(command, enable_input)

    # Launch the process and set up pipes.
    if enable_input:
        stdin = subprocess.PIPE
    else:
        stdin = None
    child = subprocess.Popen(command, stdin=stdin)

    # Wait a second for output.
    time.sleep(1)

    # Terminate the child if it hasn't finished.
    if child.poll() == None:
        child.terminate()

    print '\n-----' # Print a separator


commands = ('cmd', 'python', 'timeout 1')
for command in commands:
    run_command(command, enable_input=False)
    run_command(command, enable_input=True)

 
输出:

command="cmd", enable_input=False:
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\>
-----
command="cmd", enable_input=True:
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\>
-----
command="python", enable_input=False:
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
-----
command="python", enable_input=True:

-----
command="timeout 1", enable_input=False:

Waiting for 0 seconds, press a key to continue ...

-----
command="timeout 1", enable_input=True:
ERROR: Input redirection is not supported, exiting the process immediately.

-----

 
下面的回答提到,有些程序会尝试判断它们是被人类操作还是被脚本运行。这种情况在这里也适用吗?如果是的话,它们在Windows上是怎么判断的呢?

为什么给subprocess.Popen提供stdin会导致写入stdout的内容发生变化?

1 个回答

3

是的,有些程序在你使用管道或重定向输入时会表现得不一样。你可以这样来检测:

import sys
print sys.stdin.isattty()   # True if it's a terminal, False if it's redirected

这个方法在*nix系统和Windows系统上都可以使用。

撰写回答