python os.system 中的大括号

Curly braces in os.system on python

在 linux 终端中,我可以删除目录中的所有文件,包括隐藏文件:

sudo rm -rf /path/to/folder/{*,.*} 2> /dev/null

我正在尝试通过 os.system 在 python 中 运行 以下命令:

>>> os.system('sudo rm -rf /path/to/folder/{*,.*}')

这将无任何错误地退出(退出代码 0),但不要删除任何内容。

我理解这里可能大括号有特殊含义,但尝试 \{*,.*\} 不会有任何改变。

想知道这里发生了什么以及如何告诉 python 在终端中使用大括号。

当然要完成我能做的工作:

os.system('sudo rm -r /path/to/folder/* /path/to/folder/.myHiddenFile')  # or other combination

但我想在这里了解如何使用花括号。

os 只是帮助您进行 OS 相关系统调用的一个子集。您描述的花括号扩展不是 OS 相关的功能,它是 bash 的习惯用法。通常,我怀疑即使在其他(非bash)外壳中它也可用。

bash 花括号功能解析您的花括号表达式并使用规则将其转换为更冗长的表达式。如果您 google“bash 大括号”,您可以阅读更多关于它 here 以及互联网上其他地方的信息。

如果您想做类似于 bash 大括号对文件 所做的事情 ,请查看 python 库 glob。如果你想做类似于 bash 大括号对文本 或 对数字 所做的事情,你可以查看 itertools 也许吧。 (或者,在所有这些情况下,也许您真的只想编写一个简单的 for 循环。)

os.system调用C标准库函数system,执行带/bin/sh -c的命令。

由于您使用的大括号扩展是 bash 功能,因此根本无法理解 os.system 使用的底层 shell。

要解决此问题,您可以通过使用 -c 参数调用 /bin/bash(或 bash 所在的任何位置)来显式执行 bash 中的命令。例如

os.system("/bin/bash -c 'sudo rm -rf /path/to/folder/{*,.*}'")

注意:由于 sudo.

需要使用单引号

os.system 不进行 shell 扩展。这意味着大括号保持原样,而不是像您在终端中习惯的那样被替换。要获得此功能,您可以使用 subprocess.runshell=True:

import subprocess, shlex

result = subprocess.run(shlex.split("sudo rm -rf /path/to/folder/{*,.*}"), shell=True) # shlex.split converts the string into an argument list

print("rm exited with exit code %s, and printed following output\n%s\n and following errors\n%s\n" % (result.exitcode, result.stdout, result.stderr))