如何用jshell执行java脚本?

问题描述 投票:0回答:5

考虑到 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.

还有其他方法可以做到这一点吗?

java shebang java-9 jshell
5个回答
41
投票

使用

//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
当然是可选的,但会立即反馈该工具正在运行。

额外命令行选项--execution local

可防止
jshell
生成另一个虚拟机。这会加快启动时间,如果您的脚本代码抛出异常,本地虚拟机将退出。

请参阅

jshell --help

jshell --help-extra
 的输出以了解更多选项。

更新

另请查看

https://github.com/jbangdev/jbang 享受 Java 脚本编写的乐趣,它为从命令行运行 .java

 文件提供了一个简洁的包装器。


6
投票
事实证明,有一点技巧,有一种方法,虽然我还没有完全设法抑制解释的命令,但非常接近我想要的。

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
    

4
投票
下面的也有效;将其放入

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

)是实现此目的的强制技巧。通过更改 
/home/gigi/.sdkman/candidates/java/current/bin/java
 使用您拥有的 Java 版本。
灵感来自
https://blog.codefx.org/java/scripting-java-shebang/.


2
投票
受到斯坦尼答案的启发,我想出了一个更通用的解决方案

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

本质上:

jshell-wrapper

将删除脚本的第一行(应该是shebang)并在脚本末尾添加一个
/exit

    


0
投票
#!/usr/bin/awk NR>1{print|"jshell -"} System.out.println("Hello world!");
    
© www.soinside.com 2019 - 2024. All rights reserved.