0

Some interactive commands output differently if stdin is piped. Why is that?

Below I test subprocess.Popen on 3 different commands, with and without stdin piped.

 
Code:

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)

 
Output:

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.

-----

 
Answers to the question linked below suggest that some programs try to detect whether they're being run by a human or a script. Is that the case here? And if so, how do they detect that on Windows?

Why does supplying stdin to subprocess.Popen cause what is written to stdout to change?

1 Answer 1

3

Yes, some programs do behave differently if you are piping or redirecting input. You can detect it like this:

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

This works on *nix as well as on Windows.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! In that case, I have another question: Is there a way to masquerade as a terminal (in Windows)?
It's not a great solution, but serial ports may be treated as terminals (depending on the context) so if you're desperate enough you could try using a null-modem emulator such as com0com or a derivative thereof.
I plan to distribute my program, so I think that would add too much bulk. But it is an interesting idea.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.