Shell command fails from python, ok from shell

前端 未结 2 1739
隐瞒了意图╮
隐瞒了意图╮ 2021-01-21 09:19

I have a python script that generates a number of shell commands from the given input. The problem is that when it tries to execute the generated commands, it fails, but when i

相关标签:
2条回答
  • 2021-01-21 09:53

    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/ \;"
    
    0 讨论(0)
  • 2021-01-21 09:56

    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
    
    0 讨论(0)
提交回复
热议问题