1

I want to run a number of shell commands inside python, and I'd like to have them being outputted on the fly (similar to the way they would come in bash).

To do so I'm using:

import subprocess
cmd='''
x=1
while [ $x -le 5 ]; do
  echo "$x"
  x=$(( $x + 1 ))
  sleep 2
done
'''
out=subprocess.run(cmd,
    check=True, shell=True,stdin=PIPE, stdout=PIPE, stderr=STDOUT)
out.stdout

Questions:

  1. However, I only get the full output when the script ends. Is there a way to get it as it goes?
  2. In case it is relevant, I actually don't need to get anything from my run (i.e. not going to pipe it or anything.). Should I instead be using os.system?
Sos
  • 1,783
  • 2
  • 20
  • 46

2 Answers2

1

You can use Popen.

from subprocess import Popen, PIPE
cmd = '''
x=1
while [ $x -le 5 ]; do
  echo "$x"
  x=$(( $x + 1 ))
  sleep 2
done
'''
out = Popen(
    cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE
).communicate()[0].decode("utf-8")
print(out)
dildeolupbiten
  • 1,314
  • 1
  • 15
  • 27
  • Sorry, but I don't see the output being printed as it comes out (i.e. with the 2 seconds wait time). Is it because I'm on jupyter/ipython? – Sos Jul 22 '19 at 13:45
  • Hmm. Really I don't know, but I got the results. It printed out the numbers. – dildeolupbiten Jul 22 '19 at 13:46
  • 1
    I've tested it again in terminal, and it returns the same. My main point was getting the output *on the fly*, rather than all at the end of the evaluation. Meaning, I would see the numbers being printed with the 2 seconds interval – Sos Jul 22 '19 at 13:48
  • It is waiting 10 seconds. I guess it's because you wrote 5 to the cmd. 5 * 2 = 10 seconds. – dildeolupbiten Jul 22 '19 at 13:52
  • Exactly. But my question was how to get the output as it is being printed, rather than having `Popen`, or `subprocess` waiting for the full evaluation run. I see now that [someone else](https://stackoverflow.com/questions/4417546/constantly-print-subprocess-output-while-process-is-running) had the same question – Sos Jul 22 '19 at 13:53
  • I understood what you wanted to do. – dildeolupbiten Jul 22 '19 at 13:56
0

You could use subpocess.check_output():

co = subprocess.check_output(cmd, shell=True)
print(co.decode('utf-8'))
F. Win
  • 390
  • 5
  • 17