How to pass arguments to a jshell script?

最后都变了- 提交于 2019-12-03 11:36:15

问题


Question

I am willing to pass arguments to a jshell script. For instance, I would have liked something like this:

jshell myscript.jsh "some text"

and then to have the string "some text" available in some variable inside the script.

However, jshell only expects a list of files, therefore the answer is:

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

Is there any way to properly pass arguments to a jshell script?

Workaround so far

My only solution so far is to use an environment variable when calling the script:

ARG="some test" jshell myscript.jsh

And then I can access it in the script with:

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

回答1:


And what about option -R

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

for script

{
  String value = System.getProperty("a");
  System.out.println("a="+value);
}
/exit

will give you

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

Another way, would be following:

{
  class A {
    public void main(String args[])
    {
        for(String arg : args) {
          System.out.println(arg);
        }
    }
  }

  new A().main(System.getProperty("args").split(" "));
}

and execution

> jshell -R-Dargs="aaa bbb ccc" ./file_2.jsh

Update

Previous solution will fail with more complex args. E.g. 'This is my arg'.

But we can benefit from ant and it's 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")));
}

and then, we can call it like this:

jshell --class-path ./ant.jar -R-Dargs="aaa 'Some args with spaces' bbb ccc" ./file_2.jsh
aaa
Some args with spaces
bbb
ccc

Of course, ant.jar must be in the path that is passed via --class-path




回答2:


Oracle really screwed this up, there is no good way to do this. In addition to @mko's answer and if you use Linux(probably will work on Mac too) you can use process substitution.

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

And then you can just use arg in myscript.jsh for example:

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

You can simplify it with some bash function and probably write a batch file that will write to a temp file and do the same on windows.




回答3:


It's completely beyond me how Oracle could ignore this. 8-() But anyway: if your system uses bash as shell, you can combine this approach replacing the shebang with the idea to (ab-)use system properties to transport the whole command line into a variable:

//usr/bin/env jshell --execution local "-J-Da=$*" "$0"; exit $?
String commandline = System.getProperty("a");
System.out.println(commandline);
/exit

This way, you can call the script on the commandline simply adding the arguments: thisscript.jsh arg1 arg2 would print arg1 arg2.

Please note that this joins all parameters into one String, separated by one space. You can split it again with commandline.split("\s"), but please be aware that this isn't exact: there is no difference between two parameters a b and one parameter "a b".

If you have a fixed number of arguments, you can also pass all of these into separate system properties with "-J-Darg1=$1" "-J-Darg2=$1" "-J-Darg3=$1" etc. Please observe that you have to use -R-D... if you are not using --execution local

Another variant is generating the script on the fly with bash's process substitution. You can use such a script also simply as thisscript.jsh arg1 arg2 also on Unix-like systems having a bash.

#!/usr/bin/env bash
jshell <(
cat <<EOF
System.out.println("$1");
System.out.println("$2");
/exit
EOF
)

This allows to access individual parameters, though it will break when there are double quotes or other special characters in a parameter. Expanding on that idea: here's a way to put all parameters into an Java String array, quoting some of those characters:

#!/usr/bin/env bash
set -- "${@//\\/\\\\}"
set -- "${@//\"/\\\"}"
set -- "${@/#/\"}"
set -- "${@/%/\",}"
jshell <(
cat <<EOF
String[] args = new String[]{$@};
System.out.println(Arrays.asList(args));
/exit
EOF
)

The set -- statements double backslashes, quote double quotes and prefix a " and append a ", to transform the arguments into a valid Java array.




回答4:


With java 11 works this way:

#!/bin/java --source 11

public class JShellTest {
    public static void main(String[] args) {
        System.out.println(args.length);
    }
}

The JShellTest.main method will automatically be called when running the script, e.g.:
./jShellTest.jsh arg0 arg1 arg2 ... argN.



来源:https://stackoverflow.com/questions/46756421/how-to-pass-arguments-to-a-jshell-script

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!