0

I wrote following program for an example --

from subprocess import *
import shlex


def pipe(command):
    proc = Popen(shlex.split(command), stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    print "output:", out       # blank
    print "errors:", err       # expected output
    #return str(err)           # returns expected output
    return str(out)            # returns blanked output


out = pipe('python --version')
print 'pipe returned ----- %s' % out

Actually, err holds the expected value instead of out.

  1. What is wrong with this code?
  2. Is subprocess module is only used to handle basic OS's commands?
testuser
  • 793
  • 3
  • 13
  • 35

1 Answers1

2

The main error is the unfounded assumption that version information will be displayed on standard output. This is poorly standardized, but Python - and many other Unix tools - sends this output to standard error.

Somewhat less crucially, you should probably be using subprocess.run() instead of raw Popen(); and not import *.

from subprocess import run, PIPE

out = run(['python', '--version'],
    stdout=PIPE, stderr=PIPE, universal_newlines=True,
    check=True).stderr

If you like shlex you can use that to split the command into a list of two strings, though it seems rather superfluous in this case.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • See also https://stackoverflow.com/a/51950538/87418 for (a lot) more details. – tripleee Jan 30 '19 at 13:55
  • As the duplicate reveals, newer versions of Python actually print version information to stdout, since 3.4. – tripleee Jan 30 '19 at 14:31
  • It's basically the same means I need to choose `stderr` no matter whether the process is initiated with `run` or `Popen()`. Actually, it goes back to --- ***Python - and many other Unix tools - sends this output to standard error***. Anyway, thanks for your great answer that provided in the comment section. – testuser Jan 30 '19 at 14:33