sachin dubey
sachin dubey

Reputation: 779

How to open terminal and run a command to it in python?

I want to open a terminal and run a command using python . I want to run rsync command and see live progress of that command on terminal . I can use subprocess and grab the output of rsync but i can get output only after finish of subprocess . I want live progress of the rsync command on terminal.

Code:

import subprocess

command = subprocess.Popen(["rsync -apvr source destination --progress"], shell=True, stdout=subprocess.PIPE)

out, err = command.communicate()

can anyone tell me how to do it ?

Upvotes: 1

Views: 194

Answers (1)

Giacomo Alzetta
Giacomo Alzetta

Reputation: 2479

First of all: you do not need shell=True. Use this instead:

subprocess.Popen(["rsync", "-apvr", "source", "destination", "--progress"], stdout=subprocess.PIPE)

Or, if you don't want to manually split the command line:

import shlex

subprocess.Popen(shlex.split("rsync -apvr source destination --progress"), stdout=subprocess.PIPE)

Second: communicate waits the end of the process. If you want to actually mix the output of the subprocess with the current process you can simply avoid specifying stdout=subprocess.PIPE, or maybe you could specify stdout=sys.stdout if you want to be explicit:

import sys

subprocess.Popen(["rsync", "-apvr", "source", "destination", "--progress"], stdout=sys.stdout)

this will print the output of rsync in the stdout of your process.

If you instead want to parse the output "in real time" you'll have to use stdout=subprocess.PIPE and read from Popen.stdout manually:

proc = subprocess.Popen(["rsync", "-apvr", "source", "destination", "--progress"], stdout=sys.stdout)

for line in proc.stdout:
    do_something(line)

Depending on exactly what you want to do you may want to use the select module to get "non blocking reads" etc.

Upvotes: 2

Related Questions