Groovy: использование амперсанда в параметре командной строки

Вот отличный сценарий:

param = args[0]
println(param)

Вот как я запускаю его (Windows 7):

groovy test.groovy a&b

Я ожидаю, что этот сценарий печатает a&b, но вместо этого get 'b' не распознается как внутренняя или внешняя команда, работающая программа или пакетный файл.

Я пытался поместить аргумент (a&b в моем случае) в кавычки, но это не помогает. С двойными кавычками скрипт зависает. С одинарными кавычками я получаю ту же ошибку, что и без кавычек.

Вопрос: возможно ли взять строку с амперсандом в качестве аргумента командной строки для groovy script?

1 ответ

Решение

При выполнении groovy на Windows мы на самом деле выполняем %GROOVY_HOME\groovy.bat а затем (из groovy.bat):

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

Если мы посмотрим внутрь startGroovy.batмы можем увидеть действительно уродливый хак с аргументами (отрывок ниже):

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.

и вызывая бесконечный цикл, в то время как "уходят".

Вы можете увидеть это с set DEBUG=true перед запуском вашего скрипта.

Добавив еще один хак к куче хаков, вы также можете убежать & аналогичным образом в startGroovy.bat следующее:

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%

и эскейп...

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" что дает 8 в консоли UNIX, но висит (бесконечный цикл) в Windows.

Другие вопросы по тегам