Python子进程通配符用法

Cem*_*mre 58 python subprocess wildcard

import os

import subprocess

proc = subprocess.Popen(['ls','*.bc'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

out,err = proc.communicate()

print out
Run Code Online (Sandbox Code Playgroud)

此脚本应打印带有.bc后缀的所有文件,但它会返回一个空列表.如果我在命令行中手动执行ls*.bc它可以工作.在脚本中执行['ls','test.bc']也可以,但由于某些原因,星形符号不起作用..任何想法?

Nik*_* B. 70

您需要提供shell=True通过shell解释器执行命令.但是,如果这样做,则不能再提供列表作为第一个参数,因为参数将被引用.而是指定原始命令行,因为它希望将其传递给shell:

 proc = subprocess.Popen('ls *.bc', shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

  • @Cemre:这通常是可取的,因为你*不希望shell解释参数.想象一下,您将用户输入传递给命令,如''ls'+ user_supplied_pa​​th`.用户可以输入路径`; shutdown -s`,系统会停止!如果使用`['ls',user_supplied_pa​​th]`,则会阻止这种注入. (12认同)
  • 在动态情况下,这可能非常危险。``Popen("ls " + filename, shell=True)``,其中文件名等于 ``blahblah; rm -rf /``. 这是[我的变体](/sf/answers/3547791831/) (2认同)

dbr*_*dbr 56

扩大*水珠是外壳的一部分,但默认subprocess没有通过壳发送你的命令,所以该命令(第一自变量,ls执行),则一个文字*被用作一个参数.

这是一件好事,请参阅子流程文档的"常用参数"部分中的警告块.它主要讨论安全问题,但也可以帮助避免愚蠢的编程错误(因为没有魔术shell字符需要担心)

我与主诉shell=True是它通常意味着有更好的方法去的问题-你的榜样,你应该使用glob模块:

import glob
files = glob.glob("*.bc")
print files # ['file1.bc', 'file2.bc']
Run Code Online (Sandbox Code Playgroud)

这将更快(没有进程启动开销),更可靠和跨平台(不依赖于具有ls命令的平台)