gpt4 book ai didi

batch-file - 如何避免 cmd.exe 解释 shell 特殊字符,例如 < > ^

转载 作者:行者123 更新时间:2023-12-02 23:01:14 25 4
gpt4 key购买 nike

我有一个 Windows CMD 脚本,它接受多个参数并执行 EXE,首先传递一些硬编码的参数,然后传递来自用户的所有参数。 CMD 脚本如下所示:

launcher.exe paramX paramY %*

用户将从 Windows shell 执行 CMD 脚本,如下所示:

launcher.cmd param1 param2 param3 [...]

我遇到的问题是,如果 CMD 脚本的参数包含 shell 特殊字符,例如 < >^ ,用户被迫通过在每个前面加上 3 个插入符 ^ 来转义这些内容。 shell 转义字符。

两个示例

1) 传递参数ten>one对于 EXE,用户必须按如下方式启动 CMD:

launcher.cmd ten^^^>one

出现这种情况的原因是shell特殊字符^>由命令 shell 在两个级别上解释,第一个在命令行上,第二个在 CMD 脚本内。因此,shell 与插入符号一起逃逸 ^ shell 转义字符必须应用两次。问题是这对用户来说并不明显并且看起来很丑。

对于此示例,更好的解决方案是用双引号将参数引起来。但是,对于在参数中包含文字双引号的更复杂的示例,这种情况会出现问题。

2) 传递参数"^对于 EXE,用户必须按如下方式启动 CMD:

launcher.cmd "\"^^^^"

就我而言,我希望支持包含任何低位 ASCII 字符序列的参数,不包括控制字符,即代码点 0x20 到 0x7E。据我所知,有些示例中用户必须使用插入符号转义某些 shell 特殊字符。但是,我希望用户在这些情况下每次都必须使用 3 插入符号,只是因为他们碰巧调用的是 CMD 脚本而不是 EXE。

我可以通过用具有相同功能的 EXE 替换 CMD 脚本来解决此问题。但是,是否有任何方法可以更改 CMD 脚本,以便将其参数传递给 EXE,而不解释 shell 特殊字符?

最佳答案

一种方法是在批处理内部使用延迟扩展,因为这样特殊字符就会失去“特殊”含义。

唯一的问题是将参数放入变量中。

这样的事情可能会有所帮助

@echo off
setlocal DisableDelayedExpansion
rem ** At this point the delayedExpansion should be disabled
rem ** otherwise an exclamation mark in %1 can remove carets
set "param1=%~1"

setlocal EnableDelayedExpansion
rem ** Now you can use the param1, independent of the content, even with carets or quotes
rem ** but be careful with call's, because they start a second round of expansion
echo !param1!
set "tmp=!param1:~1,4!"

现在参数可以用引号引起来,因此不再需要插入符号。例子launcher.bat "abc>def&geh%ijk|lmn^opq!"

唯一剩下的有问题的特殊字符似乎是引号。

[编辑/改进]我创建了另一种检索参数的方法,我假设它可以接受任何字符串,也是您的第二个示例。
即使是非常硬的字符串,例如

启动器“^
发射器十^>一
启动器“&”^&

@echo off
setlocal DisableDelayedExpansion
set "prompt=X"
for %%a in (1 ) do (
@echo on
for %%b in (4) do (
rem #%1#
)
) > XY.txt
@echo off
for /F "delims=" %%a in (xy.txt) DO (
set "param=%%a"
)
setlocal EnableDelayedExpansion
set param=!param:~7,-4!
echo param='!param!'

它是如何工作的?
我发现在不扩展“或^”等特殊字符的情况下扩展%1的唯一方法是在REM语句中(对于REM来说这并不完全正确,但那是另一个故事了)好吧,唯一的问题是 REM 是一个备注,没有任何作用:-)

但是,如果您使用echo on,rem 行也会在执行之前回显(execute for rem 是一个好词)。
下一个问题是它显示出来并且您无法使用正常的> debug.txt 重定向此调试输出。如果您使用 for 循环也是如此。

好的,您可以使用类似的调用来重定向 echo on 输出

echo on
call :myFunc > debug.txt

但是如果您调用函数,您将无法再访问批处理文件的 %1。

但是使用双 for 循环,可以激活调试输出的重定向,并且仍然可以访问 %1。
我将提示符更改为“X”,因此我知道它始终只有一个字符长。

剩下的唯一一件事就是解释为什么我将 # 附加到 %1。
这是因为,在某些情况下,即使是在 REM 行中,也能识别一些特殊字符,显然;-)

rem This is a remark^
rem This_is_a_multiline^
rem "This is also a multiline"^

因此 # 抑制可能的多行情况。

关于batch-file - 如何避免 cmd.exe 解释 shell 特殊字符,例如 < > ^,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3813370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com