Windows 上的目录参数在传递给 Python 时将尾部反斜杠替换为双引号
Directory parameter on Windows has trailing backslash replaced with double quote when passed to Python
我在将 Windows 中的引用目录传递到 Python 时看到一个烦人的尾随双引号。
这是我的Python测试程序,print_args.py
:
import sys
print(sys.argv)
这是我从命令行 运行 得到的结果。注意引用的目录是Windowsshell中tab补全生成的标准格式。由于路径中的空格,需要双引号。
>py print_args.py -test "C:\Documents and Settings\"
['print_args.py', '-test', 'C:\Documents and Settings"']
结尾的反斜杠已替换为双引号,大概是因为 Python 将其读作带引号的双引号,而不是将其与前导引号匹配。
如果我没有将参数传递给 Python,而是将它传递给一个批处理脚本,它只是回应它,那么我得到了预期的尾部反斜杠。
所以在 CMD shell 和 Python 之间的某处看到 sys.argv 有一些解析影响了反斜杠和双引号。
谁能照亮一下?
编辑添加:
进一步阅读表明 Python 正在对 windows 命令行参数进行一些解析以构造 sys.argv。我认为 Windows 将整个命令行字符串(在本例中大部分未更改)传递给 Python 并且 Python 使用其自己的内部逻辑将其分解为 sys.argv 中的字符串列表。作为一种特殊情况,此处理必须允许转义双引号。我很高兴看到一些文档或代码...
您需要转义反斜杠,因为反斜杠本身就是 Python 和 PowerShell 的转义字符。否则,\"
意味着传入一个 "
文字而不是用它来包围字符串。以下对我来说很好用:
PS> py print_args.py -test "C:\Documents and Settings\"
输出:
['rando.py', '-test', 'C:\Documents and Settings\']
Windows 上的命令行处理尚未完全标准化,但在 Python 和许多其他程序的情况下,它使用 Microsoft C 运行时行为。这是指定的,例如 here。它说
A string surrounded by double quote marks is interpreted as a single argument, which may contain white-space characters. [...] If the command line ends before a closing double quote mark is found, then all the characters read so far are output as the last argument.
A double quote mark preceded by a backslash (") is interpreted as a literal double quote mark (").
这两条规则中的第二条规则防止第二个双引号被读取为终止参数 - 而是附加一个双引号。然后第一条规则允许参数结束时没有终止双引号。
注意这部分还说
The command line parsing rules used by Microsoft C/C++ code are Microsoft-specific.
这在使用 PowerShell 时更加令人困惑。
PS> py print_args.py -test 'C:\Documents and Settings\'
['print_args.py', '-test', 'C:\Documents and Settings"']
此处 PowerShell 解析保留了最后的反斜杠并删除了单引号。然后它在将命令行传递给 C 运行时之前添加双引号(因为路径中有空格),C 运行时根据规则对其进行解析,转义 PowerShell 添加的双引号。
然而,这一切都符合记录的行为,并不是错误。
我在将 Windows 中的引用目录传递到 Python 时看到一个烦人的尾随双引号。
这是我的Python测试程序,print_args.py
:
import sys
print(sys.argv)
这是我从命令行 运行 得到的结果。注意引用的目录是Windowsshell中tab补全生成的标准格式。由于路径中的空格,需要双引号。
>py print_args.py -test "C:\Documents and Settings\"
['print_args.py', '-test', 'C:\Documents and Settings"']
结尾的反斜杠已替换为双引号,大概是因为 Python 将其读作带引号的双引号,而不是将其与前导引号匹配。
如果我没有将参数传递给 Python,而是将它传递给一个批处理脚本,它只是回应它,那么我得到了预期的尾部反斜杠。
所以在 CMD shell 和 Python 之间的某处看到 sys.argv 有一些解析影响了反斜杠和双引号。
谁能照亮一下?
编辑添加:
进一步阅读表明 Python 正在对 windows 命令行参数进行一些解析以构造 sys.argv。我认为 Windows 将整个命令行字符串(在本例中大部分未更改)传递给 Python 并且 Python 使用其自己的内部逻辑将其分解为 sys.argv 中的字符串列表。作为一种特殊情况,此处理必须允许转义双引号。我很高兴看到一些文档或代码...
您需要转义反斜杠,因为反斜杠本身就是 Python 和 PowerShell 的转义字符。否则,\"
意味着传入一个 "
文字而不是用它来包围字符串。以下对我来说很好用:
PS> py print_args.py -test "C:\Documents and Settings\"
输出:
['rando.py', '-test', 'C:\Documents and Settings\']
Windows 上的命令行处理尚未完全标准化,但在 Python 和许多其他程序的情况下,它使用 Microsoft C 运行时行为。这是指定的,例如 here。它说
A string surrounded by double quote marks is interpreted as a single argument, which may contain white-space characters. [...] If the command line ends before a closing double quote mark is found, then all the characters read so far are output as the last argument.
A double quote mark preceded by a backslash (") is interpreted as a literal double quote mark (").
这两条规则中的第二条规则防止第二个双引号被读取为终止参数 - 而是附加一个双引号。然后第一条规则允许参数结束时没有终止双引号。
注意这部分还说
The command line parsing rules used by Microsoft C/C++ code are Microsoft-specific.
这在使用 PowerShell 时更加令人困惑。
PS> py print_args.py -test 'C:\Documents and Settings\'
['print_args.py', '-test', 'C:\Documents and Settings"']
此处 PowerShell 解析保留了最后的反斜杠并删除了单引号。然后它在将命令行传递给 C 运行时之前添加双引号(因为路径中有空格),C 运行时根据规则对其进行解析,转义 PowerShell 添加的双引号。
然而,这一切都符合记录的行为,并不是错误。