Python 的 os.system 默认无法识别 "**" 通配符

作者: , 共 910 字 , 共阅读 0

在 Python 里,我们可以直接用 os.system 来执行系统命令(假设下面的 strip 是一个可以处理多个文件的第三者程序):

os.system("strip ./*.csv")

上面的例子里,它还支持通配符,将处理当前目录下所有的 csv 文件。如果写下面这个(正式名字叫做 globalstar ),预期它能处理当前目录以及所有子目录下所有的 csv 文件,我们会发现它并没有效果:

os.system("strip ./**/*.csv")

而我们直接在命令行执行strip ./**/*.csv却能达到效果。这说明os.system支持了 shell 环境的展开,但并没有完整地支持。更深层次的原因是默认的 sh 默认不支持双星号通配符展开,但 zsh 等更现代的 shell 默认支持。对于 bash shell ,我们可以通过修改系统参数来让它支持"**"(这不足以解决上面的问题,因为 os.system 默认使用的是 sh ):

shopt -s globstar

我们只能用glob.glob 来替代:

import glob

files = glob.glob("./**/*.csv", recursive=True)
os.system("strip " + " ".join(files))

题外话: os.system 的运行环境

下面代码可以得到 os.system 默认的 shell 环境是 sh (注意它并不是当前的$SHELL 变量):

import os
os.system("echo $0")      # sh
os.system("echo $SHELL")  # /bin/zsh

所以修改$SHELL 变量是没有用的。要想明确使用的环境,需要直接指定:

import os  
os.system("/bin/zsh -c 'your_command'")

Q. E. D.

类似文章:
编程 » Python
在 Python 中,有时候为了获取当前运行的脚本的同目录下的另外一个文件,会这么写:
编程 » C++
要在C++中运行系统命令,可以直接使用std::system函数:
主要形式是下面三种。后面两种实际指向同一个位置(如果path是一个已存在的文件夹),但处理结果会有所差异。
编程 » Python
Python 在搜索模块时,依次搜索sys.path里的位置,直到找到模块为止。下面命令可以查看当前的搜索路径:
IT » Python, Ubuntu
主要是update-alternatives命令的使用。
编程 » django, requests, python
这里的 requests 是指 Python 的 requests 包。
编程 » Python
今天写一段程序时遇到一个问题,查了好一会才搞清楚。代码可以简化为下面这个小代码:
命令行参数的初步说明,请参考argparse 模块用法实例详解,写的很清晰而详细。
编程 » Shell, VBA
某些时候,我们需要在 Excel 中调用命令行或者 Bash 脚本, VBA 可以通过 Shell 函数很方便地做到这一点。以下用ipconfig /all来举例,这条命令行语句用来获得机器的网路配置信息,包括 IP、网关等信息。它可以替换成任何一个 bash 脚本和命令行代码。
IT » Linux
假设一个目录下有很多很多".bak"文件,如果我们直接用rm命令删除:
五名童军从立水桥出发,沿清河北岸的清河滨水慢行系统,骑到温榆河交叉点再往北,从温榆河大桥到温榆河的东岸;再往南骑到机场高速,最后从温榆河的西岸和清河的南岸骑回立水桥。
绿野六名童军,去走了海坨山。这次运气很好,山顶雨雾缭绕,又没有下雨,感受非常好。