在处理我的previous问题时,我遇到了一个类似的问题,我最初正在解决这个问题。批处理 - 如何正确分配可能包含引号的任意百分号(%1)或百分号(%*)参数?
实际上,本月我花了一个试图创建一个通用.bat帮助程序库,它将尽可能最好地处理任何名称的拖放文件。我想为调用者透明地执行此操作,并向后兼容任何现有的脚本,因此文件名以%1,%2的形式提供,并且我没有任何问题。
@MCND的解决方案是读取%CMDCMDLINE%
,然后棘手的解析它。因此,我可以简单地写入set "a=%CMDCMDLINE:"=?%"
- 并将完整字符串转换为变量A,但里面的所有引号会立即替换为问号?
,从而生成一个未加引号的行,我可以进一步轻松地进行处理。
但它只适用于.bat拖放,因为这样我无法读取从命令提示符传递的参数。我必须使用%*
。
我现在的问题是:如果参数中还可能包含引号字符,甚至是不配对,怎么看?
考虑以下BAT文件:(姑且称之为“C:\ test.bat的”)
@echo off
echo START
setlocal enabledelayedexpansion
set a=%1
echo a=[!a!]
set b="%1"
echo b=[!b!]
set "c=%1"
echo c=[!c!]
set d=%~1
echo d=[!d!]
set e="%~1"
echo e=[!e!]
set "f=%~1"
echo f=[!f!]
set g=%*
echo g=[!g!]
set h="%*"
echo h=[!h!]
set "i=%*"
echo i=[!i!]
endlocal
echo DONE
exit /b
基本上它是我能想象到读取进入批量(“呼叫”)百分比参数的一切:表格%1
,%~1
,%*
未加引号的set x=y
,引用set "x=y"
并明确引用set x="y"
变体。延迟扩展只是为了安全地回应该值(为了简单起见,我不在意参数中的检查标记!
)。
我最终的目标是创建一个永远不会抛出错误的脚本:因此,每个可能的错误都应该在我的代码执行之前出现(在CMD提示符本身之前),或者在完成之后(当调用者尝试访问一个名字不全的文件)。
所以在这个例子中,在START和DONE之间理想情况下应该没有错误,但是它们会在相应的“回声”之前出现在“设置”指令处。
尝试#1
命令:test
输出:
START
a=[]
b=[""]
c=[]
d=[]
e=[""]
f=[]
g=[]
h=[""]
i=[]
DONE
好,不是零个参数错误。让我们得到一些:
尝试#2
命令:test 123 "56"
输出:
START
a=[123]
b=["123"]
c=[123]
d=[123]
e=["123"]
f=[123]
g=[123 "56"]
h=["123 "56""]
i=[123 "56"]
DONE
看起来像 “正常” 的字符串的任何方法工作没有错误。
尝试3
命令:test ^&-
输出:
START
'-' is not recognized as an internal or external command,
operable program or batch file.
a=[]
b=["&-"]
c=[&-]
'-' is not recognized as an internal or external command,
operable program or batch file.
d=[]
e=["&-"]
f=[&-]
'-' is not recognized as an internal or external command,
operable program or batch file.
g=[]
h=["&-"]
i=[&-]
DONE
正如你所看到的,情况A,d和G失败(=%1
,=%~1
和=%*
)。
尝试#4
命令:test "&-"
输出:
START
a=["&-"]
'-""' is not recognized as an internal or external command,
operable program or batch file.
b=[""]
'-""' is not recognized as an internal or external command,
operable program or batch file.
c=[]
'-""' is not recognized as an internal or external command,
operable program or batch file.
d=[]
e=["&-"]
f=[&-]
g=["&-"]
'-""' is not recognized as an internal or external command,
operable program or batch file.
h=[""]
'-""' is not recognized as an internal or external command,
operable program or batch file.
i=[]
DONE
现在例B,C,d,H和I是失败(="%1"
,"=%1"
,=%~1
,="%*"
和"=%*"
)。
尝试#5
命令:test ""^&-"
输出:
START
'-"' is not recognized as an internal or external command,
operable program or batch file.
a=[""]
b=["""&-""]
c=[""&-"]
d=["&-]
'-"' is not recognized as an internal or external command,
operable program or batch file.
e=[""]
'-"' is not recognized as an internal or external command,
operable program or batch file.
f=[]
'-"' is not recognized as an internal or external command,
operable program or batch file.
g=[""]
h=["""&-""]
i=[""&-"]
DONE
无法与A和G沿其余2案件E和F(="%~1"
和"=%~1"
)(=%1
和%*
)。
因此,没有任何“set”变种可以在所有试图破坏我的代码的情况下可靠地工作!
我是否缺少一些其他方法来读取来自不可信源的当前参数?
我可以在正常变量%…%
中获得%…
吗?我可以在%…
中直接替换报价"
吗?我可以将%*
放在某些特殊的情况下,例如&符号&
可能不会导致更改执行吗?是否有另一种方法来获取参数(再次调用CMD,使用临时文件 - 任何东西?)
即使它会在这些情况下销毁原始字符串(未成对的引号,未转义的特价等),但我很好,但我需要摆脱解析错误(导致不受控制的代码执行)!
尝试#5:尝试改变'测试“”^& - “'测试”“^& - ^”'...... – aschipfl