通过Windows批处理/命令脚本将感叹号(!)传递到Groovy脚本

时间:2019-04-25 16:56:35

标签: batch-file groovy

从Windows命令行中将包含感叹号(!)的参数传递到groovy脚本会被剥离,因为Windows试图使用延迟扩展来扩展变量名(请参见this,{{3} }和this)。发布了很多解决方案,其中包含以下解决方案之一:

  • setlocal ENABLEDELAYEDEXPANSION
  • 转义为“带引号^!”
  • 不加引号的转义^^!

这些都是公认的答案,因此在某些情况下显然可以使用,但不适用于我。这是我在Windows 10专业版上得到的行为:

C:\sof>type cmdtest.groovy
PASSWD=args[0]
println PASSWD

C:\sof>groovy cmdtest.groovy foopasswd!
foopasswd

C:\sof>groovy cmdtest.groovy foopasswd^^!
foopasswd

C:\sof>groovy cmdtest.groovy "foopasswd^!"
foopasswd

C:\sof>setlocal DisableDelayedExpansion

C:\sof>groovy cmdtest.groovy foopasswd!
foopasswd

C:\sof>groovy cmdtest.groovy foopasswd^^!
foopasswd

我认为它是在groovy.bat中发生的,所以我也尝试将setlocal DisableDelayedExpansion添加到groovy.bat上,但也没有用。

能以某种方式告诉我使上述cmdtest.groovy尊重!的诀窍吗?

1 个答案:

答案 0 :(得分:1)

问题出在文件groovy.batstartgroovy.bat上,它们包含不良的批处理代码。
startgroovy.bat启用延迟扩展,但不使用它!

使用该行中的groovy.bat,将参数从startgroovy.bat传递到%*

"%DIRNAME%\startGroovy.bat" "%DIRNAME%" groovy.ui.GroovyMain %*

第一个插入号将被删除,但是有多少个未确定,因为是否启用延迟扩展并不可靠。 在startgroovy.bat中,启用了延迟扩展,并且参数由类似set CP=%~2的行存储。
接下来的插入符号将被删除。
但是当参数到达块时:

rem escape minus (-d), quotes (-q), star (-s).
set _ARGS=%*
if not defined _ARGS goto execute
set _ARGS=%_ARGS:-=-d%
set _ARGS=%_ARGS:"=-q%
...

失去了所有希望,在这里不可能保留感叹号

如果要修复此问题,则需要将所有%ARGS:...%表达式替换为-!ARGS:...!

set _ARGS=!_ARGS:-=-d!
set _ARGS=!_ARGS:"=-q!

但是功能:win9xME_args_loop也已损坏。

:win9xME_args_loop
rem split args by spaces into first and rest
for /f "tokens=1,*" %%i in (!_ARGS!) do call :get_arg "%%i" "%%j"
goto process_arg

call ... "%%i" "%%j"不能与插入号/感叹号一起使用,必须将其重构为类似以下内容:

for /f "tokens=1,*" %%i in ("!_ARGS!") do (
   set "_ARG=!_ARG! %%~i"

但是我的结论是:请勿尝试在密码中使用特殊字符。
必须完全重写groovy批处理文件,目前这些文件是反模式的一个很好的例子