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.