Pelicanux

Just A Few Random Words

Subprocess Python Module

Well, this is quite a long time I haven’t been writing a post to my blog. Not that I have nothing to write, but these days, I have learnt a lot a very new topics; it requires some time to really assimilate them, and writing a post is a quite time consumming task as well.

Enough with telling the story of my life, today, I will present a few stuff I find quite usefull with the subprocess module of python.

Here is a basic usecase with subprocess

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
import subprocess

cmd='ls -la'
c = subprocess.Popen(
  cmd.split(' '),
  shell = False,
  stdout = subprocess.PIPE,
  stderr = subprocess.PIPE
)

o,e = subprocess.communicate(c)

if e:
  print 'Error: '+str(e)
  sys.exit(1)
print o

Basically subprocess lets you launch command from the system. Contrary to the os.system command, it lets you get back stdout and stderr.

Some more complex cases

I struggled a lot with more complicated commands, especially those with a lot of single and double quotes such as:

1
hexdump -ve '1/1 "%.2x"' $file

When its is just bash scripting, one can concatenate simple and double quotes easilly; but here is a pythonic way to do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import shlex
import subprocess

# By the way, here is how to concatenate
# simple and double quotes in bash scripts
cmd = "hexdump -ve "+"'"+"1/1 "+'"'+"%.2x"+'"'+"'"
listed_cmd = shlex.split(cmd)

c = subprocess.Popen(
  listed_cmd,
  shell = False,
  stdout = subprocess.PIPE,
  stderr = subprocess.PIPE,
)
o,e = subprocess.communicate(c)

How to pipe commands one into one other

Ok, here is how to specify file python with the previews command (one can just add this to the cmd variable, but I find it ugly, and beautiful is better than ugly:

1
2
3
4
5
6
7
c = subprocess.Popen(
  listed_cmd,
  shell = False,
  stdout = subprocess.PIPE,
  stderr = subprocess.PIPE,
  stdin = open(filename, 'r'),
)

The exact same way may be used to chain commands:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
address = 'philippe [ à ] pelicanux.net'
content = 'Just a few random fancy chars'
subject = 'Email subject to cautious'

p1 = subprocess.Popen(
  ['echo', content],
  shell = False,
  stdout = subprocess.PIPE,
  stderr = subprocess.PIPE,
)
p2 = subprocess.Popen(
  ['mail', '-s', subject, address],
  shell = False,
  stdout = subprocess.PIPE,
  stderr = subprocess.PIPE,
  stdin = p1.stdout,
)
p1.stdout.close()
o,e = p2.communicate()

That’s all for today!