如何用jshell执行java脚本?

时间:2017-07-05 03:36:25

标签: java shebang java-9 jshell

鉴于Java 9已经出现在我们面前,我们终于可以使用jshell进行java REPL了,我希望有一种方法可以将一个shebang添加到脚本中并让jshell解释它。

我尝试创建test.jsh

#!/usr/bin/env jshell -s
System.out.println("Hello World")
/exit

然而,这给出了:

⚡ ./test.jsh
|  Error:
|  illegal character: '#'
|  #!/usr/bin/env jshell -s
|  ^
|  Error:
|  illegal start of expression
|  #!/usr/bin/env jshell -s
|    ^
Hello World

事实证明,在OpenJDK https://bugs.openjdk.java.net/browse/JDK-8167440中存在增强请求。

还有其他办法吗?

4 个答案:

答案 0 :(得分:17)

使用

//usr/bin/env jshell --show-version --execution local "$0" "$@"; exit $?

作为test.jsh的第一行。 test.jsh脚本可能如下所示:

//usr/bin/env jshell --show-version "$0" "$@"; exit $?
System.out.println("Hello World")
/exit

命令行选项--show-version当然是可选的,但会立即反馈工具正在运行

extra 命令行选项--execution local阻止jshell生成另一个VM。这会加快启动时间,如果脚本代码抛出异常,则本地VM将退出。

请参阅jshell --helpjshell --help-extra的输出以获取更多选项。

答案 1 :(得分:4)

事实证明,虽然我没有完全设法抑制解释的命令但是非常接近我想要的东西,但有一点诡计有一种方法。

test.jsh更改为:

#!/usr/bin/env sh
tail -n +4 "$0" | jshell -s "$@"
exit $?
System.out.println("Hello World")
/exit

这给了我们:

⚡ ./test.jsh
-> System.out.println("Hello World")
Hello World
-> /exit

答案 2 :(得分:2)

受到灵感回答的启发,我想出了一个更通用的解决方案

https://gist.github.com/ffissore/012d7e32a096fde5266f49038c93dcaf

本质上:jshell-wrapper将删除脚本的第一行(应该是shebang)并在脚本末尾添加/exit

答案 3 :(得分:0)

以下内容也适用;将其放入someScript.jsh文件中,然后使用./someScript.jsh运行它。 someScript.jsh收到的所有参数将转到String[] args

#!/home/gigi/.sdkman/candidates/java/current/bin/java --source 11

import java.util.Arrays;
import ro.go.adrhc.*; // example of using your classes, e.g. App below

public class X {
    public static void main(String[] args) {
        // do whatever you want here, e.g.:
        // System.out.println("Hello World");
        // or
        // use a class:
        // App.main(args);
        // e.g. from ro.go.adrhc package, by running:
        // CLASSPATH="/path-to-ro.go.adrhc-classes" ./someScript.jsh 
    }
}

包装类的使用(此处为X)是使之起作用的强制技巧。
https://blog.codefx.org/java/scripting-java-shebang/的启发。