在Windows上执行
groovy
时,我们实际上是执行
%GROOVY_HOME\groovy.bat
,然后(来自
groovy.bat
):
"%DIRNAME%\startGroovy.bat" "%DIRNAME%" groovy.ui.GroovyMain %*
如果我们查看
startGroovy.bat
的内容,可以看到一个非常丑陋的hack来处理参数(下面是一段摘录):
rem horrible roll your own arg processing inspired by jruby equivalent
rem escape minus (-d), quotes (-q), star (-s).
set _ARGS=%*
if not defined _ARGS goto execute
set _ARGS=%_ARGS:-=-d%
set _ARGS=%_ARGS:"=-q%
set _ARGS=%_ARGS:?=-n%
rem Windowz will try to match * with files so we escape it here
rem but it is also a meta char for env var string substitution
rem so it can't be first char here, hack just for common cases.
rem If in doubt use a space or bracket before * if using -e.
set _ARGS=%_ARGS: *= -s%
set _ARGS=%_ARGS:)*=)-s%
set _ARGS=%_ARGS:0*=0-s%
set _ARGS=%_ARGS:1*=1-s%
set _ARGS=%_ARGS:2*=2-s%
set _ARGS=%_ARGS:3*=3-s%
set _ARGS=%_ARGS:4*=4-s%
set _ARGS=%_ARGS:5*=5-s%
set _ARGS=%_ARGS:6*=6-s%
set _ARGS=%_ARGS:7*=7-s%
set _ARGS=%_ARGS:8*=8-s%
set _ARGS=%_ARGS:9*=9-s%
因此,在
startyGroovy.bat
文件中,
"a&b"
被"
转义"为
-qa&b-q
,导致脚本内出现两个命令,如下所示:
'b-q' is not recognized as an internal or external command,
operable program or batch file.
当进行“取消转义”时,可能会导致无限循环。
在运行Groovy脚本之前,可以使用set DEBUG=true
来查看。
通过以下方式,在startGroovy.bat
中增加另一个hack来逃避同样的问题:转义&
。
rem escape minus (-d), quotes (-q), star (-s).
rem jalopaba escape ampersand (-m)
set _ARGS=%*
if not defined _ARGS goto execute
set _ARGS=%_ARGS:-=-d%
set _ARGS=%_ARGS:&=-m%
set _ARGS=%_ARGS:"=-q%
set _ARGS=%_ARGS:?=-n%
and unescape...
rem now unescape -s, -q, -n, -d
rem jalopaba unescape -m
rem -d must be the last to be unescaped
set _ARG=%_ARG:-s=*%
set _ARG=%_ARG:-q="%
set _ARG=%_ARG:-n=?%
set _ARG=%_ARG:-m=&%
set _ARG=%_ARG:-d=-%
因此:
groovy test.groovy "a&b"
a&b
不确定在Windows中是否存在更清晰/更优雅的解决方案。
您可以看到类似情况,例如groovy -e "println 2**3"
在UNIX控制台中产生8
,但在Windows中会出现无限循环(死循环)。
groovy test a^&b
,但是没有成功吗?你使用的是哪个“shell”?只是普通的cmd
还是其他的?我真的怀疑这不是一个Groovy的问题。 - cfrick