【问题标题】:Curly braces in os.system on pythonpython上os.system中的花括号
【发布时间】:2021-07-04 10:19:12
【问题描述】:

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

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

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

>>> 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

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

【问题讨论】:

标签: python bash curly-braces


【解决方案1】:

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,需要使用单引号。

【讨论】:

  • 天啊,我怎么没想到呢? +1 !
  • 是的,这很棒,效果很好,解释也很好。谢谢
【解决方案2】:

os 只是帮助您进行与操作系统相关的系统调用的子集。您描述的花括号扩展不是与操作系统相关的功能,它是一个 bash 习惯用法。作为一项规则,我怀疑它甚至在其他(非 bash)shell 中也可用。

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

如果您想做类似于 bash 花括号对文件所做的操作,请查看 python 库 glob。如果您想做类似于 bash 花括号 on texton numbers 的操作,您可以查看itertools。 (或者,在所有这些情况下,也许你真的只想写一个简单的 for 循环。)

【讨论】:

    【解决方案3】:

    os.system 不做外壳扩展。这意味着花括号保持原样,不会像您在终端中习惯的那样被替换。要获得此功能,您可以使用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))
    

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 2019-01-26
      • 2020-08-09
      • 1970-01-01
      • 2014-04-18
      • 2018-01-08
      • 2012-01-18
      • 2012-01-27
      相关资源
      最近更新 更多