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
Post a Comment