考虑到 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.
还有其他方法可以做到这一点吗?
使用
//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
文件提供了一个简洁的包装器。
将
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
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 版本。灵感来自
#!/usr/bin/awk NR>1{print|"jshell -"}
System.out.println("Hello world!");