Eri*_*ric 2 powershell escaping batch-file
这是我的args.bat档案:
@echo off
python -c "import sys; print(sys.argv)" %*
Run Code Online (Sandbox Code Playgroud)
我在这里调用python因为我确切地知道如何解释输出,而不是猜测字符串中的引号
如果我从cmd调用它会发生什么:
>.\args.bat ^^^^^
More?
More?
['-c', '^']
>.\args.bat "^^^^^"
['-c', '^^^^^']
Run Code Online (Sandbox Code Playgroud)
但这是powershell的作用:
PS> .\args.bat ^^^^^
['-c', '^']
PS> .\args.bat "^^^^^"
['-c', '^']
PS> .\args.bat '^^^^^'
['-c', '^']
PS> .\args.bat "'^^^^^'"
['-c', '^']
PS> .\args.bat '"^^^^^"'
['-c', '^^^^^']
Run Code Online (Sandbox Code Playgroud)
为什么在从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', '^^^^^']
Run Code Online (Sandbox Code Playgroud)
但是从PowerShell调用python批处理时仍然存在!
PS> python -c "import subprocess; subprocess.call(['args.bat', '^^^^^'])"
['-c', '^']
Run Code Online (Sandbox Code Playgroud)
从cmd的python批处理:
> python -c "import subprocess; subprocess.call(['args.bat', '^^^^^'])"
['-c', '^']
Run Code Online (Sandbox Code Playgroud)
有关批处理文件是否可以稳健地传递任意参数的更大问题(扰流警报:否),请参阅Eric的后续问题.
tl;博士:
PS> .\args.bat --% "^^^^^"
['-c', '^^^^^']
Run Code Online (Sandbox Code Playgroud)
使用--%,停止解析符号,使PowerShell通过原样传递剩余的参数,除了扩展cmd.exe样式的环境变量引用,如%OS%.
相反,您将无法引用PowerShell变量或表达式.
PowerShell作为一个独立的shell,首先执行自己的解析,然后 - 在Windows上一个不幸的必要- 在为外部程序编写命令行时重新应用引用.
它的做法随着时间的推移而发生变化,并且是过去许多问题的根源.--%然而,如上所述,这些问题导致了其具有其自身挑战的引入.
然而,重新引用通常是必要的,因为PowerShell的语法不一定被外部程序理解.
最值得注意的是,'...'不能假设所有外部程序都能理解引用,因此需要转换为"...".
但是,PowerShell会根据是否认为有必要而有条件地重新引用.
在手头的情况下,由于内容的的PowerShell的 "^^^^^"字符串包含没有空格,PowerShell的决定不要引用它通过批处理文件时,它; 即:
.\args.bat "^^^^^"
Run Code Online (Sandbox Code Playgroud)
有效地成为
.\args.bat ^^^^^
Run Code Online (Sandbox Code Playgroud)
对于大多数^没有语法意义的外部程序来说这很好,但是在批处理文件(由解释cmd.exe)的情况下,它很重要,因为^函数作为转义字符.在那里没有引用字符串.
要在此方案中仍然强制使用双引号,作为上述--%方法的替代方法,您可以使用嵌入式双引号,如您在问题中已经演示的那样:
PS> .\args.bat '"^^^^^"' # '...' quoting with embedded "..." quoting
['-c', '^^^^^']
Run Code Online (Sandbox Code Playgroud)
从powershell调用python不存在同样的问题:
PS> python -c "import sys; print(sys.argv)" "^^^^^"
那是因为cmd.exe没有涉及这种情况,即使从PowerShell调用时丢失了封闭的双引号,Python ^也会将实例视为文字.
但是当从PowerShell调用python批处理时仍然存在
PS> python -c "import subprocess; subprocess.call(['args.bat', '^^^^^'])"从cmd的python批处理:
> python -c "import subprocess; subprocess.call(['args.bat', '^^^^^'])"
那是因为你再次调用一个批处理文件 - 在这种情况下甚至是不加引号 ,因为封闭只对Python具有语法意义并且没有通过 - 这重新引入了特殊的解释.^^^^^cmd.exe'....'^
请注意,即使是"无shell"调用批处理文件(例如subprocess.call()来自Python)的方法仍然总是会调用cmd.exe,因为cmd.exe执行批处理文件需要解释器.
当将未加引号的字符串^^^^^传递给批处理文件时,似乎有两轮解释:首先,作为参数解析的一部分,每^^对成为单个^,任何非配对^被丢弃.因此,在批处理文件中,您会看到^^,当使用不带引号时,它会变为单个^- 如果您双引号%*或%1在批处理文件中,您将看到^^已通过.
| 归档时间: |
|
| 查看次数: |
81 次 |
| 最近记录: |