批处理文件 – 如何避免cmd.exe解释shell特殊字符,如<> ^
我有一个
Windows CMD脚本接受多个参数并执行一个EXE,先传递一些硬编码的参数,然后从用户的所有参数. CMD脚本如下所示:
launcher.exe paramX paramY %* 用户将从Windows shell执行CMD脚本,如下所示: launcher.cmd param1 param2 param3 [...] 我的问题是,如果CMD脚本的参数包含shell特殊字符,如< >和^,用户被迫通过前面的每个具有3个插入符号shell转义字符来解除它们. 两个例子 1)要将参数10> 1传递给EXE,用户必须按如下方式启动CMD: launcher.cmd ten^^^>one 其原因是shell特殊字符^和>由命令shell在两个级别解释,首先在命令行和第二个CMD脚本中.所以,用脱字符^ shell转义字符转义的shell必须被应用两次.问题是这对用户来说是不明显的,看起来很丑陋. 对于这个例子,一个更好的解决方案是用双引号来围绕参数.但是,这个例子比较复杂,在参数中包含一个文字双引号. 2)要将参数“^”传递给EXE,用户必须按如下方式启动CMD: launcher.cmd ""^^^^" 在我的情况下,我想支持包含任何低ASCII字符序列的参数,不包括控制字符,即代码点0x20到0x7E.我知道会有一些例子,用户必须使用插入符号来转义某些外壳特殊字符.但是,我不希望用户在这些情况下每次都要使用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!" 现在参数可以用引号括起来,所以不再需要插入. 唯一剩下的有问题的特殊字符似乎是引号. [编辑/改善] 发射器“^ @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!' 怎么运行的? 但是如果你使用echo也可以在它们被执行之前echo线回显(执行rem是一个很好的词). 好的,你可以通过一个调用来重定向输出的echo echo on call :myFunc > debug.txt 但是,如果调用函数,则不能再访问批处理文件的%1. 但是通过双重循环,可以激活调试输出的重定向,并且仍然可以访问%1. 唯一剩下的就是解释为什么我添加一个#到%1. rem This is a remark^ rem This_is_a_multiline^ rem "This is also a multiline"^ 所以#抑制可能的多线情况. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |