Как передать аргументы в jshell script?
Вопрос
Я готов передать аргументы в jshell script. Например, мне понравилось бы что-то вроде этого:
jshell myscript.jsh "some text"
а затем, чтобы строка "некоторый текст" была доступна в некоторой переменной внутри script.
Однако jshell
ожидает только список файлов, поэтому ответ:
File 'some text' for 'jshell' is not found.
Есть ли способ правильно передать аргументы в jshell script?
Обходной путь
Моим единственным решением до сих пор является использование переменной среды при вызове script:
ARG="some test" jshell myscript.jsh
И затем я могу получить доступ к нему в script с помощью:
System.getenv().get("ARG")
Ответы
Ответ 1
А как насчет опции -R
> jshell -v -R-Da=b ./file.jsh
для script
{
String value = System.getProperty("a");
System.out.println("a="+value);
}
/exit
предоставит вам
> jshell -v -R-Da=b ./file.jsh
a=b
Другой способ:
{
class A {
public void main(String args[])
{
for(String arg : args) {
System.out.println(arg);
}
}
}
new A().main(System.getProperty("args").split(" "));
}
и выполнение
> jshell -R-Dargs="aaa bbb ccc" ./file_2.jsh
Обновление
Предыдущее решение завершится неудачей с более сложными аргументами. Например. 'This is my arg'
.
Но мы можем воспользоваться ant
и CommandLine
class
import org.apache.tools.ant.types.Commandline;
{
class A {
public void main(String args[])
{
for(String arg : args) {
System.out.println(arg);
}
}
}
new A().main(Commandline.translateCommandline(System.getProperty("args")));
}
и тогда мы можем назвать это следующим образом:
jshell --class-path ./ant.jar -R-Dargs="aaa 'Some args with spaces' bbb ccc" ./file_2.jsh
aaa
Some args with spaces
bbb
ccc
Конечно, ant.jar
должен находиться в пути, который передается через --class-path
Ответ 2
Oracle действительно испортил это, нет хорошего способа сделать это. В дополнение к @mko answer, и если вы используете Linux (вероятно, будете работать и на Mac), вы можете использовать замену процесса.
jshell <(echo 'String arg="some text"') myscript.jsh
И тогда вы можете просто использовать arg
в myscript.jsh
, например:
System.out.println(arg) // will print "some text"
Вы можете упростить его с помощью некоторой функции bash и, возможно, написать командный файл, который будет записывать в файл temp и делать то же самое в окнах.
Ответ 3
Это полностью вне меня, как Oracle мог игнорировать это. 8-() Но в любом случае: если ваша система использует bash в качестве оболочки, вы можете объединить этот подход, заменив shebang идеей (ab-) использовать системные свойства для переноса всей командной строки в переменную:
//usr/bin/env jshell --execution local "-J-Da=$*" "$0"; exit $?
String commandline = System.getProperty("a");
System.out.println(commandline);
/exit
Таким образом, вы можете вызвать скрипт в командной строке, просто добавив аргументы: thisscript.jsh arg1 arg2
выведет arg1 arg2
.
Обратите внимание, что это объединяет все параметры в одну строку, разделенные одним пробелом. Вы можете снова разделить его с помощью commandline.split("\s")
, но имейте в виду, что это не точно: нет разницы между двумя параметрами ab
и одним параметром "ab"
.
Если у вас есть фиксированное количество аргументов, вы также можете передать все их в отдельные системные свойства с помощью "-J-Darg1=$1" "-J-Darg2=$1" "-J-Darg3=$1"
и т.д. Обратите внимание, что вы должны использовать -RD...
если вы не используете --execution local
Другой вариант - создание сценария на лету с заменой процесса bash. Вы можете использовать такой скрипт также просто, как thisscript.jsh arg1 arg2
также в Unix-подобных системах, имеющих bash.
#!/usr/bin/env bash
jshell <(
cat <<EOF
System.out.println("$1");
System.out.println("$2");
/exit
EOF
)
Это позволяет получить доступ к отдельным параметрам, но будет прерываться, если в параметре есть двойные кавычки или другие специальные символы. В продолжение этой идеи: вот способ поместить все параметры в массив строк Java, заключив в кавычки некоторые из этих символов:
#!/usr/bin/env bash
set -- "${@//\\/\\\\}"
set -- "${@//\"/\\\"}"
set -- "${@/#/\"}"
set -- "${@/%/\",}"
jshell <(
cat <<EOF
String[] args = new String[]{[email protected]};
System.out.println(Arrays.asList(args));
/exit
EOF
)
Операторы set --
выполняют двойную обратную косую черту, заключают в кавычки двойные кавычки и set --
префикс "
и добавить а ",
чтобы преобразовать аргументы в допустимый массив Java.