【问题标题】:Shell expansions are not performed when running a command with `subprocess.call' with `shell=True'使用 `subprocess.call' 和 `shell=True' 运行命令时,不执行 Shell 扩展
【发布时间】:2019-11-03 11:27:09
【问题描述】:

我正在尝试使用 python 构建一些文件,但它以错误的方式执行它。

我尝试在 linux 中构建一些文件。 当我在终端中使用“make ./package/feeds/proj/{clean,compile} V=s”命令时,它工作正常,但是当我尝试使用 python 脚本运行它时,使用命令“p = subprocess.call(r'/usr/bin/make package/feeds/proj/{clean,compile} V=s',shell = True))”,它的行为有所不同。

日志:

在终端运行时:

make[1]: Entering directory '/local/mnt/workspace/rubaeshk/unused2/qsdk'
make[2]: Entering directory '/local/mnt/workspace/rubaeshk/unused2/qsdk/package/feeds/whc/qca-whc-crash-log'
rm -f /local/mnt/workspace/rubaeshk/unused2/qsdk/bin/ipq/packages/whc/qca-whc-crash-log_*
..(log continued until successfully built)

通过 python 脚本运行时:

WARNING: your configuration is out of sync. Please run make menuconfig, oldconfig or defconfig!
make[1]: Entering directory '/local/mnt/workspace/rubaeshk/unused2/qsdk'
make[1]: *** No rule to make target 'package/feeds/whc/qca-whc-crash-log/{clean,compile}'.  Stop.
make[1]: Leaving directory '/local/mnt/workspace/rubaeshk/unused2/qsdk'
/local/mnt/workspace/rubaeshk/unused2/qsdk/include/toplevel.mk:186: recipe for target 'package/feeds/whc/qca-whc-crash-log/{clean,compile}' failed
make: *** [package/feeds/whc/qca-whc-crash-log/{clean,compile}] Error 2

谁能看看哪里出错了..

【问题讨论】:

    标签: python linux makefile subprocess os.system


    【解决方案1】:

    大括号扩展不是标准外壳的一部分;它是除了 POSIX 之外的一些 shell(如 bash)提供的附加功能。当您在 Python 中运行 subprocess.call 时,它可能使用的是 /bin/sh,而不是 /bin/bash

    所以,写出来:package/feeds/whc/qca-whc-crash-log/clean package/feeds/whc/qca-whc-crash-log/compile

    【讨论】:

      【解决方案2】:

      正如subprocess.Popen documentation 中解释的(subprocess.call 像所有其他便利函数一样委托给Popen),Unix 中的subprocess.call('command', shell=True) 相当于运行argv

      ['/bin/sh', '-c', 'command']
      

      并且sh 不支持大括号扩展(这是{a,b} 语法的正式名称)。

      要改为使用bash 运行命令,您需要覆盖使用executable 参数的shell 可执行文件:

      p = subprocess.call('command', shell=True, executable='/bin/bash')
      

      例子:

      $ python -c 'import subprocess; subprocess.call("echo /usr/{lib,bin}", shell=True, executable="/bin/bash")'
      /usr/lib /usr/bin
      

      但请注意,不鼓励使用 shell=True,因为它本质上是特定于平台的,取决于本地 shell 及其设置,并且如果您使用不受信任的输入,则可能是错误或安全漏洞。最好手动构建命令行并传递生成的argv。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-12
        • 1970-01-01
        • 2012-03-21
        • 1970-01-01
        • 2015-02-13
        • 2023-03-18
        • 2018-10-06
        相关资源
        最近更新 更多