1

In my program I want to let the user either run a shell command or execute a binary file. No matter how much I read about subprocess.Popen I can't figure out a way to replicate the os.system() functionality.

I simply want to echo $USER but nothing seems to work.

Turning shell=True..

>>> subprocess.Popen(['echo', '$USER'], shell=True,\ stdout=subprocess.PIPE,\ stderr=subprocess.PIPE).communicate() >>> ('\n', '') 

Passing current environment vars..

>>> subprocess.Popen(['echo', '$USER'], shell=True,\ env=os.environ\ stdout=subprocess.PIPE,\ stderr=subprocess.PIPE).communicate() >>> ('\n', '') 

So what's the proper way to run a shell command?

------- Edit: requirements ---------

Some people posted answers but maybe I should be more specific. I want to keep both stdout, stderr and return value stored somewhere. All answers seem to give either the one or the other.

4
  • 2
    Why don't you just use os.environ['USER']? Commented Feb 12, 2016 at 12:47
  • 1
    or even better, import getpass and getpass.getuser() for cross-os compatibility. Commented Feb 12, 2016 at 12:48
  • 1
    @DanielRoseman because I don't know what commands the user will run so it's easier to just pass all the environments.. Commented Feb 12, 2016 at 12:52
  • related: subprocess.call() arguments ignored when using shell=True w/ list Commented Feb 13, 2016 at 13:34

3 Answers 3

1

Thanks to massiou direction I figured out the answer. The culprit is that when using shell=True you should pass the whole command as a single string!

>>> subprocess.Popen(['echo $USER'], shell=True, \ stdout=subprocess.PIPE,\ stderr=subprocess.PIPE).communicate() >>> ('manos\n', '') 

The reason is that the first argument in the list will be the one executed as a shell script. The rest arguments are for the shell program itself.

Sign up to request clarification or add additional context in comments.

Comments

1

use call method

subprocess.call('echo $USER',shell=True) 

Altarnetivly:

var = subprocess.check_output('echo $USER',shell=True) # .rstrip('\n') print var 

Also with subprocess.Popen()

process = subprocess.Popen("echo $USER",shell=True,stdout=subprocess.PIPE) print process.communicate()[0], 

3 Comments

That seems to work but I can't seem to save the output in a variable then..
@Pithikos then go with check_output
thanks, that works. Then though I get no return code. That's why I started with using Popen.. I would prefer to keep all stderr, stdout, return code.
0

You can just do something like:

subprocess.call('echo $USER', shell=True) 

Also, take a look at Replacing Older Functions with the subprocess Module

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.