Как передать аргументы скрипту jshell?

Вопрос

Я готов передать аргументы скрипту jshell. Например, мне бы понравилось что-то вроде этого:

jshell myscript.jsh "some text"

а затем иметь строку "некоторый текст", доступную в некоторой переменной внутри скрипта.

Тем не мение, jshell ожидает только список файлов, поэтому ответ:

File 'some text' for 'jshell' is not found.

Есть ли способ правильно передать аргументы в сценарий jshell?

Обходной путь до сих пор

Пока что мое единственное решение - использовать переменную окружения при вызове скрипта:

ARG="some test" jshell myscript.jsh

И тогда я могу получить к нему доступ в сценарии с помощью:

System.getenv().get("ARG")

4 ответа

Решение

А как насчет варианта -R

> jshell -v -R-Da=b ./file.jsh

для сценария

{
  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 учебный класс

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

Oracle действительно облажался, нет хорошего способа сделать это. В дополнение к ответу @mko, и если вы используете Linux(вероятно, будет работать и на Mac), вы можете использовать подстановку процессов.

jshell <(echo 'String arg="some text"') myscript.jsh

И тогда вы можете просто использовать arg в myscript.jsh например:

System.out.println(arg) // will print "some text"

Вы можете упростить это с помощью некоторой функции bash и, возможно, написать командный файл, который будет записывать во временный файл и делать то же самое в Windows.

Я совершенно не могу понять, как 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"), но учтите, что это не точно: между двумя параметрами нет никакой разницы a b и один параметр "a b",

Если у вас есть фиксированное количество аргументов, вы также можете передать их в отдельные системные свойства с помощью "-J-Darg1=$1" "-J-Darg2=$1" "-J-Darg3=$1" и т.д. Пожалуйста, обратите внимание, что вы должны использовать -R-D... если вы не используете --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[]{$@};
System.out.println(Arrays.asList(args));
/exit
EOF
)

set -- операторы ставят двойную обратную косую черту, заключают двойные кавычки и префикс " и добавить ", преобразовать аргументы в допустимый массив Java.

Недавно меня достаточно вдохновили ответы Олега и Ханса-Петера Шторра, чтобы попытаться объединить их так, чтобы а) я мог использовать обычные аргументы оболочки, б) написать обычный код Java, ожидающий ввода:

      //usr/bin/env jshell <(ARGS=; for var in "$@"; do ARGS+="\"$var\","; done; echo "String[] args = {$ARGS}") "$0"; exit $?

System.out.println("RESULT: " + Arrays.asList(args));

/exit

Используя строку заголовка Ганса, а затем встраивая, как продемонстрировал Олег, который строит аргументы [email protected] в String[] argsвар.

С этим вы можете chmod +xваш скрипт и выполните его с обычными старыми аргументами:

      ]$ ./script.jsh foo bar
RESULT: [test, bar]
Другие вопросы по тегам