-4
def run_command(command):
    p = subprocess.Popen(command,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    return p.communicate()

On running :

   command = ("git clone " + repo).split()
    run_command(commmnd)

Everything is working.But when i try to run multiple commands i got an error.

command = ("git clone www.myrepo.com/etc:etc && cd etc && git stash && git pull).split()
run_command(command)
Rus Mine
  • 1,523
  • 1
  • 18
  • 29
  • 5
    Possible duplicate of [Running shell command from Python and capturing the output](http://stackoverflow.com/questions/4760215/running-shell-command-from-python-and-capturing-the-output) – arainone Jan 16 '16 at 00:41
  • what is the question? What is wrong? What do you expect to happen? What happens instead? – jfs Jan 16 '16 at 07:21
  • I wanted to run multiple commands in one line and store the output into a variable.I don't understand why so many downvotes ? I understand that is a questioan similar about outputing shell commands . but i need to run multiple commands and output into a variable, to later display the output into a django app. ok ? – Rus Mine Jan 16 '16 at 10:55

1 Answers1

0

Use subprocess.check_output() with the shell=True option, but heed the security warning re untrusted inputs if it applies to you.

import subprocess

command = 'git clone www.myrepo.com/etc:etc && cd etc && git stash && git pull'
try:
    output = subprocess.check_output(command, shell=True)
except subprocess.CalledProcessError as exc:
    print("subprocess failed with return code {}".format(exc.returncode))
    print("message: {}".format(exc.message))

After this output contains the combined stdout of the executed processes, if it was successful. Otherwise you need to handle a CalledProcessError exception.

Alternatively, if you can not guarantee that the command strings are secure, you can perform each command in turn, progressing to the next command only if the current command's return code is 0 i.e. CalledProcessError is not raised.

import subprocess
import shlex

command = 'git clone www.myrepo.com/etc:etc && cd etc && git stash && git pull'
output = []
try:
    for cmd in command.split('&&'):
        output.append(subprocess.check_output(shlex.split(cmd)))
except subprocess.CalledProcessError as exc:
    print("{!r} failed with return code {}".format(' '.join(exc.cmd), exc.returncode))
else:
    print(''.join(output))

While this is more secure with regard to shell command injection, it is still possible for sensitive arguments to be sniffed by other users for example with ps.

mhawke
  • 84,695
  • 9
  • 117
  • 138
  • with the shell=True , everything works fine .. but this is a very insecure – Rus Mine Jan 16 '16 at 02:19
  • @RusMine: if you don't use untrusted input to construct `command` then why do you think `shell=True` is "very insecure" compared to running similar commands manually? – jfs Jan 16 '16 at 07:25
  • It can be insecure if you do not control the strings comprising the command, or the command line arguments are sensitive in some way, e.g. contains a key, password, credit card etc. Otherwise it should be OK. – mhawke Jan 16 '16 at 07:28
  • many thanks for your answers :) . but can you tell me the difference between subprocess.Popen and subprocess.check_output ? because adding shell=True on my script ,everything seems to work – Rus Mine Jan 16 '16 at 10:56