为什么在从PowerShell调用批处理文件时插入符会消失?
为什么在从PowerShell调用批处理文件时插入符会消失?
这是我的args.bat
文件:
@echo off python -c "import sys; print(sys.argv)" %*
我在这里调用python,因为我知道如何解释输出,而不是猜测字符串中的引号在哪里。
如果我从cmd中调用它,会发生以下情况:
>.\args.bat ^^^^^
还有吗?
还有吗?
['-c', '^']
>.\args.bat "^^^^^"
['-c', '^^^^^']
但是在powershell中会发生以下情况:
PS> .\args.bat ^^^^^ ['-c', '^'] PS> .\args.bat "^^^^^" ['-c', '^'] PS> .\args.bat '^^^^^' ['-c', '^'] PS> .\args.bat "'^^^^^'" ['-c', '^'] PS> .\args.bat '"^^^^^"' ['-c', '^^^^^']
为什么在从powershell调用批处理文件时必须对参数进行双引号引用?
从powershell中调用python时不存在同样的问题:
PS> python -c "import sys; print(sys.argv)" "^^^^^" ['-c', '^^^^^'] PS> python -c "import sys; print(sys.argv)" '^^^^^' ['-c', '^^^^^'] PS> python -c "import sys; print(sys.argv)" ^^^^^ ['-c', '^^^^^']
但是在从powershell调用python从批处理中调用时仍然存在此问题!
PS> python -c "import subprocess; subprocess.call(['args.bat', '^^^^^'])" ['-c', '^']
以及从python从cmd中调用批处理:
> python -c "import subprocess; subprocess.call(['args.bat', '^^^^^'])" ['-c', '^']
为什么从PowerShell调用批处理文件时插入符消失?
问题的出现的原因:
在调用批处理文件时,PowerShell会重新应用引号,这是为了确保外部程序能够正确解析PowerShell的语法。然而,在某些情况下,PowerShell会认为重新应用引号是不必要的,这就导致了插入符消失的问题。具体来说,在没有空格的情况下,PowerShell不会对参数重新应用引号,而在批处理文件中,插入符在未被引号包围的字符串中代表转义字符,因此会导致问题的出现。
解决方法:
解决这个问题的一种方法是使用--%
,即停止解析符号。使用--%
可以让PowerShell将剩余的参数原样传递给批处理文件,但是无法引用PowerShell变量或表达式。
另一种解决方法是在参数中嵌入双引号,例如:'.\args.bat '"^^^^^"'
。这样可以强制PowerShell在传递参数时使用双引号,避免插入符消失的问题。
需要注意的是,即使使用"无shell"的方法调用批处理文件(如Python的subprocess.call()
),仍然会调用cmd.exe
,因为cmd.exe
是执行批处理文件所需的解释器。
在调用批处理文件时,参数会经过两轮解释:首先,在参数解析阶段,每对^^
会变成一个^
,没有成对的^
会被丢弃。在批处理文件内部,你将看到^^
,当你在批处理文件内部对%*
或%1
使用双引号时,你将看到^^
被传递。
总之,为了避免插入符消失的问题,可以使用--%
停止解析符号或在参数中嵌入双引号来强制使用双引号传递参数。