2

I am new to the subprocess.call function and I have tried different combinations of the same call but it is not working.

I am trying to execute the following command:

cmd = 'sort -k1,1 -k4,4n -k5,5n '+outpath+fnametempout+' > '+outpath+fnameout
print cmd

If I try the call I get an error:

cmd = cmd.split(" ")
print cmd
subprocess.call(cmd)

the error I get is:

sort: stat failed: >: No such file or directory
asked Jan 17, 2013 at 19:39

3 Answers 3

13

Doing it this way, you need shell=True to allow the shell redirection to work.

subprocess.call('sort -k1,1 -k4,4n -k5,5n '+outpath+fnametempout,shell=True)

A better way is:

with open(outpath+fnameout,'w') as fout: #context manager is OK since `call` blocks :)
 subprocess.call(cmd,stdout=fout)

which avoids spawning a shell all-together and is safe from shell injection type attacks. Here, cmd is a list as in your original, e.g.

cmd = 'sort -k1,1 -k4,4n -k5,5n '+outpath+fnametempout
cmd = cmd.split()

It should also be stated that python has really nice sorting facilities and so I doubt that it is actually necessary to pass the job off to sort via a subprocess.


Finally, rather than using str.split to split the arguments, from a string, it's probably better to use shlex.split as that will properly handle quoted strings.

>>> import shlex
>>> cmd = "foo -b -c 'arg in quotes'"
>>> print cmd.split()
['foo', '-b', '-c', "'arg", 'in', "quotes'"]
>>> print shlex.split(cmd)
['foo', '-b', '-c', 'arg in quotes']
answered Jan 17, 2013 at 19:41
Sign up to request clarification or add additional context in comments.

2 Comments

+1. But the shlex thing is a bit in the wrong direction. Building a list instead of a str in the first place is always the best thing to do. If you unavoidably have an str, and you're using shell=True (or you're on Windows), just pass the str. If you do have to split the string, then yes, definitely use shlex.split rather than str.split. But that should be your last resort, not your first. In this case, there's no reason for any splitting.
another issue is that shlex.split() does not emulate the shell perfectly. It may break in subtle ways. As @abarnert said: construct the list explicitly instead of using shlex.split().
2

it is not to compecated execute above command in python:

import subprocess
import sys
proc = subprocess.Popen(['sort','-k1','1', '-k4','4n', '-k5','5n', '+outpath+fnametempout+', '>', '+outpath+fnameout'],stdin=subprocess.PIPE)
proc.communicate()
answered Oct 3, 2015 at 15:06

Comments

0

example:

subprocess.call(['ps','aux'])
lines=subprocess.check_output(['ls','-al'])
line_list = lines.split('\n')
or
handle = subprocess.Popen('ls',stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,close_fds=True)
handle.stdout.read()
answered Feb 25, 2015 at 4:15

1 Comment

OPs issue is the presence of > shell redirection operator while subprocess does not use the shell by default. And the solution is to use stdout=fout as demonstrated by @mgilson. Don't use out = handle.stdout.read() if you've used PIPE several times, use out ,err = handle.communicate(input) instead -- otherwise the subprocess may deadlock (though it is unlikely with ls here)

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.