Reputation: 2700
I'm using subprocess.Popen
to call an installation script. However, when I pipe the output to the terminal, via print
, it looses any of the formatting from the installation script output. For example, all terminal colors are gone and the download progress bar comes out on multiple lines.
Here's my code:
process = subprocess.Popen(
[script],
shell=True,
cwd=script_dir,
universal_newlines=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env={
'WORKSPACE': build_dir
})
with process.stdout:
for line in iter(process.stdout.readline, b''):
print(line)
And a sample of the output (which is usually displayed as a progress bar):
You need to run "nvm install 4.2.2" to install it before using it.
Downloading and installing node v4.2.2...
Downloading https://nodejs.org/dist/v4.2.2/node-v4.2.2-darwin-x64.tar.gz...
0.0%
1.0%
### 4.6%
####### 10.5%
############# 18.8%
################### 26.5%
######################## 34.1%
############################## 41.9%
################################### 49.7%
######################################### 57.4%
############################################## 65.2%
#################################################### 73.0%
########################################################## 80.8%
############################################################### 88.5%
##################################################################### 96.3%
######################################################################## 100.0%
Upvotes: 4
Views: 3806
Reputation: 38
No need to call 'iter'. In fact, it complained when I tried this suggestion because it's expecting a string, not bytes.
This works to redirect the exact same output:
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, universal_newlines=True)
for line in process.stdout:
sys.stdout.write(line)
sys.stdout.flush()
Upvotes: 1
Reputation: 369494
print
statement prints additional newline at the end. Use sys.stdout.write
instead:
import sys
...
with process.stdout:
for line in iter(process.stdout.readline, b''):
sys.stdout.write(line) # <--
sys.stdout.flush() # <--
BTW, you can just use subprocess.call
without capturing stdout, stderr output unless you want to process the output in your program:
subprocess.call(
[script],
shell=True,
cwd=script_dir,
env={
'WORKSPACE': build_dir
})
Upvotes: 0