Shell command fails from python, ok from shell
Since your command is a pipeline, you must set shell=True
so that subprocess will send the command, as is, to the shell:
command = 'find /home/me/downloader/0-29/ -type f | grep -i .rpm$ | xargs -i cp {} /home/me/downloader/builds/0-29/'subprocess.call(command, shell=True)
Or,
process = subprocess.Popen(command, shell=True)output = process.communicate()[0]return output
Also, do not do splitting in python on a command with a pipeline. This will result in find
being passed |
as one of its arguments instead of as a shell operator.
It also appears that the command can be simplified:
command="find /home/me/downloader/0-29/ -type f -iname '*.rpm' -exec cp {} /home/me/downloader/builds/0-29/ \;"
Since the above is no longer a pipeline, it could, with a minor modification, be split and given to subprocess with shell=False. The modification is that the single-quotes around '*.rpm'
are there to protect the glob from shell expansion. With shell=False, the shell doesn't remove them. So, we have to. For shell=False and for use with command.split()
:
command="find /home/me/downloader/0-29/ -type f -iname *.rpm -exec cp {} /home/me/downloader/builds/0-29/ \;"
I believe what you do is you start a single program called find
with many parameters, incl. |
and grep
and xargs
- and these are not arguments to find.
What you want to do is probably to ask bash to run find
and then pipe the outcome to grep
, etc. One way to do that is to execute a single command called bash
with two parameters (-c
) and a whole string incl. piped commands, e.g.
process = subprocess.Popen(["bash", "-c", "cat /etc/issue | grep a"], stdout=subprocess.PIPE)output=process.communicate()[0]print output