Subprocess module from python fails to run bash commands like "<cmd1> | <cmd2>" -


the following python script:

#!/usr/bin/env python  import os cmd = "echo hello world | cut -d' ' -f1" test=os.system(cmd) print(test) 

it runs ok (the output hello). when use subprocess module one:

#!/usr/bin/env python  import subprocess cmd = "echo hello world | cut -d' ' -f1" process = subprocess.popen(cmd.split(), stdout=subprocess.pipe) test = process.communicate()[0] print (test) 

is not ok. output hello world | cut -d' ' -f1 , expect hello. how can correct it?

i saw in general subprocess module fail when i'm using bash command like:

<cmd1> | <cmd2>  

this:

echo hello world | cut -d' ' -f1 

… not command, it's fragment of shell script. need have shell execute it.

you can adding shell=true popen constructor.


the documentation explains how works. explains better ways same thing without shell. example:

p1 = popen(['echo', 'hello', 'world'], stdout=pipe) p2 = popen(['cut', "-d' '", '-f1'], stdin=p1.stdout, stdout=pipe) p1.stdout.close() test = p2.communicate()[0] 

meanwhile, never want use split on command line—and in fact, example shows why don't want to:

>>> cmd = "echo hello world | cut -d' ' -f1" >>> cmd.split() ['echo', 'hello', 'world', '|', 'cut', "-d'", "'", '-f1'] 

notice split -d' ' 2 arguments, -d' , '.

if you're using shell=true, don't try split arguments @ all; pass string cmd:

process = subprocess.popen(cmd, stdout=subprocess.pipe, shell=true) 

if you're not using shell, right way shlex module:

>>> shlex.split(cmd) ['echo', 'hello', 'world', '|', 'cut', '-d ', '-f1'] 

notice "-d' '" turned "-d " time. may seem odd @ first glance, it's in fact shell do, , want; cut program space d option. (in other words, quotes shell, not program shell runs.)

(the shlex module has handle quote function can use exact opposite purpose: building command line list of arguments shell=true.)

however, it's better create list of arguments in first place, instead of trying figure out how create string that, when run through shlex.split(), give list wanted.


Comments

Popular posts from this blog

java - Run a .jar on Heroku -

java - Jtable duplicate Rows -

validation - How to pass paramaters like unix into windows batch file -