1

I know that it is easy to run an external command from Python and display the output on the screen. For example: (It will display the output only on the screen)

import subprocess
subprocess.Popen(['dir'])

I also know that we can run an external command from Python and get the output. For example: (It will store the output as a string in variable out and will not display the output on the screen anymore)

import subprocess
result = subprocess.Popen(['dir'], stdout=subprocess.PIPE)
out = result.stdout.read()

My question is: Is there a way to display the output on the screen and store and output in a variable simultaneously? In other words, when I run the code, the external command output will display on the screen. At the same time, a variable in the code can get the output displayed on the screen.

Update: I found out if I include stdout=subprocess.PIPE in subprocess.Popen, it will display nothing on the screen (windows command prompt).

Related questions:

live output from subprocess command

Output of subprocess both to PIPE and directly to stdout

Banghua Zhao
  • 1,518
  • 1
  • 14
  • 23

2 Answers2

1

If you need real-time output from Popen , you could use something like this (Windows platform according to your last comment):

Byte stream:

import sys, subprocess
out=b''
result = subprocess.Popen(['cmd', '/c', 'dir /B 1*.txt'], stdout=subprocess.PIPE, 
    universal_newlines=False)
for s_line in result.stdout:
    #Parse it the way you want
    out += s_line
    print( s_line.decode(sys.stdout.encoding).replace('\r\n',''))

# debugging output
print(out.decode(sys.stdout.encoding))

Text stream:

import subprocess
out=''
result = subprocess.Popen(['cmd', '/c', 'dir /B 1*.txt'], stdout=subprocess.PIPE, 
    universal_newlines=True)
for s_line in result.stdout:
    #Parse it the way you want
    out += s_line
    print( s_line.rstrip())

# debugging output
print(out)

The latter code snippet output:

>>> import subprocess
>>> out=''
>>> result = subprocess.Popen(['cmd', '/c', 'dir /B 1*.txt'], stdout=subprocess.PIPE,
...     universal_newlines=True)
>>> for s_line in result.stdout:
...     #Parse it the way you want
...     out += s_line
...     print( s_line.rstrip())
...
1.325.txt
1049363a.txt
1049363b.txt
1051416.txt
1207235log.txt
>>> print(out)
1.325.txt
1049363a.txt
1049363b.txt
1051416.txt
1207235log.txt

>>>
JosefZ
  • 28,460
  • 5
  • 44
  • 83
  • Thanks. But I still get nothing in the windows command prompt. If I include `stdout=subprocess.PIPE` in `subprocess.Popen`, it will always redirect and display nothing on the screen. – Banghua Zhao Sep 07 '17 at 17:21
1

Use | tee (On windows platform, use Powershell):

import subprocess

# Run command in powershell and redirect it by | tee to a file named out.txt 
result = subprocess.Popen(['powershell', command, '|', 'tee', 'out.txt'])

# Get standard output
f = open('out.txt')
out = f.read()
f.close()

By this way, the screen will display the output on PowerShell terminal and the output will also be stored in out.

Banghua Zhao
  • 1,518
  • 1
  • 14
  • 23