【问题标题】:Shell command fails from python, ok from shellshell命令从python失败,从shell确定
【发布时间】:2014-02-10 08:28:10
【问题描述】:

我有一个 python 脚本,可以从给定的输入生成许多 shell 命令。问题是当它尝试执行生成的命令时,它失败了,但是当我自己运行生成的命令时(即从命令行),它们成功执行。

这是生成的命令: <pre>find /home/me/downloader/0-29/ -type f | grep -i .rpm$ | xargs -i cp {} /home/me/downloader/builds/0-29/</pre>

以下是python脚本运行时的错误信息:

find:路径必须在表达式之前:|
用法:find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

您能帮我理解问题所在吗?

UPD:这是我用来执行生成的命令的函数:

def exec_command(command):
        process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
        output = process.communicate()[0]
        return output

【问题讨论】:

  • 你是如何从 python 执行该行的?提供一些代码?
  • 您可能需要在 python 中引用您的命令才能执行...

标签: python linux bash shell


【解决方案1】:

由于您的命令是管道,您必须设置shell=True 以便子进程将命令按原样发送到外壳:

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)

或者,

process = subprocess.Popen(command, shell=True)
output = process.communicate()[0]
return output

另外,不要在 python 中对带有管道的命令进行拆分。这将导致 find 被传递 | 作为其参数之一,而不是作为 shell 运算符。

看来命令也可以简化:

command="find /home/me/downloader/0-29/ -type f -iname '*.rpm' -exec cp {} /home/me/downloader/builds/0-29/ \;"

由于上面不再是一个管道,它可以通过一个小的修改被拆分并提供给 shell=False 的子进程。修改是 '*.rpm' 周围的单引号是为了保护 glob 免受 shell 扩展。使用 shell=False,shell 不会删除它们。所以,我们必须这样做。对于 shell=False 并与 command.split() 一起使用:

command="find /home/me/downloader/0-29/ -type f -iname *.rpm -exec cp {} /home/me/downloader/builds/0-29/ \;"

【讨论】:

  • 我认为您在简化版中搞砸了引号。
  • @user2357112 谢谢。修好了。
  • *.rpm周围的单引号只有在shell处理命令行时才需要,以防止模式扩展;然后,shell 在将文字字符串传递给find 之前删除引号。使用shell=False,您希望省略单引号。
【解决方案2】:

我相信你所做的是你启动了一个名为find 的程序,其中包含许多参数,包括。 |grepxargs - 这些不是要查找的参数。

想要做的可能是让 bash 运行 find,然后将结果通过管道传输到 grep 等。一种方法是执行一个名为 @ 的命令987654327@ 带有两个参数 (-c) 和一个完整的字符串,包括。管道命令,例如

process = subprocess.Popen(["bash", "-c", "cat /etc/issue | grep a"], stdout=subprocess.PIPE)
output=process.communicate()[0]
print output

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-20
    • 2018-07-30
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 2012-04-01
    相关资源
    最近更新 更多