【问题标题】:Why aren't there quotes in sys.argv when they were used at the command line?为什么在命令行中使用 sys.argv 时没有引号?
【发布时间】:2018-04-29 07:32:52
【问题描述】:

这是一个错误吗?

#!/usr/bin/env python3.6
# filename: tmp.py
import sys

print(sys.argv)

调用:

python tmp.py find . -name '*.py'

实际输出:

['tmp.py', 'find', '.', '-name', '*.py']

预期输出:

['tmp.py', 'find', '.', '-name', "'*.py'"]

请注意实际输出中缺少引号。

【问题讨论】:

  • 你为什么期待文字引号?
  • 我为什么不应该呢?我没有要求 python 做任何事情,只是在命令行中提取 实际 的内容。
  • ...也就是说,如果您调用subprocess.Popen(['foo', 'hello']),您不会(嗯,不应该)期望foo 看到文字参数hello 周围的Python 引号.同样,您不能指望其他程序看到纯粹是 shell 语法的引号,而不是传递给正在执行的软件。
  • @BrianBruggeman 它准确地提取了您在命令行中输入的内容...您的误解是围绕bash 的工作原理以及字面引号对bash 的含义...也值得尝试@987654330 @
  • ...所以,当您谈论“命令行”时——这是一个 shell 结构。当一个 UNIX 程序启动另一个 UNIX 程序时,实际调用约定是一个 C 字符串数组。

标签: python shell command-line-arguments


【解决方案1】:

不,因为您的 shell 在将参数传递给 python 之前会删除引号(否则它会扩展 *.py 通配符)

为了得到你需要的东西:

python tmp.py find -name "'*.py'"

请注意,此行为取决于 shell。在windows上,由于单引号没有特殊含义,传递'*.py',你会得到:

['tmp.py', 'find', '.', '-name', "'*.py'"]

另请注意,受引号保护的通配符在 python 方面没有真正的兴趣,因为您需要去掉引号才能使用glob.glob 评估它们

【讨论】:

    【解决方案2】:

    shell 负责将其运行的命令分解为 C 字符串列表。 这些字符串然后被传递给正在运行的程序。

    在示例中:

    python tmp.py find . -name '*.py'
    

    ...正确实现的 shell 将为 the execve syscallargv 元素生成的参数列表(在 C 语法中)如下所示:

    char[][]{ "python", "tmp.py", "find", ".", "-name", "*.py", NULL }
    

    当 Python 运行时,它不知道原来的命令是什么:它无法知道你输入的是 '*.py' 还是 \*.py 或其他任何东西;它只看到 shell 传递给操作系统的参数列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      • 1970-01-01
      • 1970-01-01
      • 2019-12-11
      • 2014-12-08
      • 2020-12-04
      • 2011-06-13
      相关资源
      最近更新 更多