Как передать аргументы скрипту 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]