JBang团队推出了JBang Jash(发音为 Jazz),这是一个 Java 库,旨在通过流畅且可预测的 API 简化外部进程和 shell 命令的执行,从而解决开发人员在使用标准 Java API(如 ProcessBuilder
和 Runtime
中定义的重载 exec()
方法)执行这些任务时面临的常见复杂性和样板代码问题。
JBang Jash 旨在促进直观且可链式的进程执行,自动处理底层的输入/输出流管理。默认情况下,非零退出代码会被视为异常,这种行为是可以自定义的。它还支持在管道中传递命令,消除了手动流转发的需求,并且还能根据操作系统自动检测相应的 shell 环境,如 Bash、CMD 或 Powershell。
以下是一个使用纯 Java 的 shell 示例,需要手动处理流并进行显式错误检查。该示例运行"git status"并捕获输出:
// 没有使用Jash
ProcessBuilder builder = new ProcessBuilder("git", "status");
builder.redirectErrorStream(true);
Process process = builder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
if (exitCode != 0) {
throw new RuntimeException("Process exited with error code " + exitCode);
}
复制代码
使用 Jash:
Jash.start("git", "status").stream().forEach(System.out::println);
复制代码
让我们再看一个如何在 Java 中管道化命令的示例,其中将小写文本转换为大写文本,并通过管道化 echo
命令的输出到 tr
命令中:
// 没有使用Jash
ProcessBuilder echoBuilder = new ProcessBuilder("echo", "hello world");
Process echoProcess = echoBuilder.start();
ProcessBuilder trBuilder = new ProcessBuilder("tr", "a-z", "A-Z");
Process trProcess = trBuilder.start();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(echoProcess.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(trProcess.getOutputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
}
writer.flush();
trProcess.getOutputStream().close(); // 向tr发送EOF信号
}
int echoExit = echoProcess.waitFor();
int trExit = trProcess.waitFor();
if (echoExit != 0) {
throw new RuntimeException("echo failed with code " + echoExit);
}
try (BufferedReader resultReader = new BufferedReader(new InputStreamReader(trProcess.getInputStream()))) {
String line;
while ((line = resultReader.readLine()) != null) {
System.out.println(line); // 预期:HELLO WORLD
}
}
if (trExit != 0) {
throw new RuntimeException("tr failed with code " + trExit);
}
复制代码
使用 Jash:
String result = Jash.start("echo", "hello world")
.pipe("tr", "a-z", "A-Z")
.get();
System.out.println(result.trim()); // 输出:HELLO WORLD
复制代码
JBang Jash 基于 OnGres,Inc.在 2020 年发布的一个名为"fluent-process"的项目。该项目已经多年没有发布官方版本了,但在 2025 年被分支并重命名为"jash"(Java 和 Shell 的缩写),以反映其专注于为 shell 进程和流提供更符合 Java 17+接口的工作。
需要注意的是,Jash 可以集成到任何 Java 项目中,无需使用 JBang CLI 工具。
更多关于 JBang Jash 的示例和详细信息,请访问其GitHub仓库。
原文链接:
https://www.infoq.com/news/2025/05/jbang-jash/
评论