这是一个错误吗?
#!/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'"]
请注意实际输出中缺少引号。
不,因为你的 shell 在将参数传递给 python 之前删除了引号(否则它会扩展
*.py
通配符)
要获得您想要的东西,您需要:
python tmp.py find -name "'*.py'"
请注意,此行为依赖于 shell。在 Windows 上,由于单引号没有特殊含义,通过
'*.py'
,你会得到:
['tmp.py', 'find', '.', '-name', "'*.py'"]
另请注意,受引号保护的通配符在 python 方面没有真正的兴趣,因为您需要去掉引号才能使用
glob.glob
评估它们
shell 负责将其运行的命令分解为 C 字符串列表。 这些字符串然后被传递给正在运行的程序。
示例中:
python tmp.py find . -name '*.py'
...正确实现的 shell 将为
的
argv
元素生成的参数列表 execve
系统调用 看起来(在 C 语法中)类似于:
char[][]{ "python", "tmp.py", "find", ".", "-name", "*.py", NULL }
当Python运行时,它不知道原始命令是什么:它无法知道你是否输入了
'*.py'
或\*.py
或任何其他东西;它只能看到 shell 传递给操作系统的参数列表。
对于 Linux 等“git bash”和 cygwin 用户:
$ type -a python
或可能 $ type -a python3
不应打印超过一行...即 python 的路径。
补救措施:确保删除除一个之外的所有内容;将一个保留为实际的可执行文件。