为什么在从PowerShell调用批处理文件时插入符会消失?

34 浏览
0 Comments

为什么在从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', '^']

0
0 Comments

为什么从PowerShell调用批处理文件时插入符消失?

问题的出现的原因:

在调用批处理文件时,PowerShell会重新应用引号,这是为了确保外部程序能够正确解析PowerShell的语法。然而,在某些情况下,PowerShell会认为重新应用引号是不必要的,这就导致了插入符消失的问题。具体来说,在没有空格的情况下,PowerShell不会对参数重新应用引号,而在批处理文件中,插入符在未被引号包围的字符串中代表转义字符,因此会导致问题的出现。

解决方法:

解决这个问题的一种方法是使用--%,即停止解析符号。使用--%可以让PowerShell将剩余的参数原样传递给批处理文件,但是无法引用PowerShell变量或表达式。

另一种解决方法是在参数中嵌入双引号,例如:'.\args.bat '"^^^^^"'。这样可以强制PowerShell在传递参数时使用双引号,避免插入符消失的问题。

需要注意的是,即使使用"无shell"的方法调用批处理文件(如Python的subprocess.call()),仍然会调用cmd.exe,因为cmd.exe是执行批处理文件所需的解释器。

在调用批处理文件时,参数会经过两轮解释:首先,在参数解析阶段,每对^^会变成一个^,没有成对的^会被丢弃。在批处理文件内部,你将看到^^,当你在批处理文件内部对%*%1使用双引号时,你将看到^^被传递。

总之,为了避免插入符消失的问题,可以使用--%停止解析符号或在参数中嵌入双引号来强制使用双引号传递参数。

0