prefer-jbang-automation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePrefer JBang for Automation
自动化优先选择JBang
Overview
概述
Prefer jbang scripts over bash commands for automation tasks.
While bash+jq/curl/awk work, jbang provides type safety, better debugging, IDE support, and maintainability. The slight overhead is worth it.
自动化任务优先选择jbang脚本而非bash命令。
虽然bash+jq/curl/awk也能实现需求,但jbang提供了类型安全、更优的调试能力、IDE支持以及可维护性,这点额外的开销是值得的。
Red Flags - STOP and Use JBang Instead
危险信号 - 立刻停止并改用JBang
If you're thinking any of these, STOP and write a jbang script instead:
- "I'll use to parse this JSON"
jq - "A quick pipeline will work"
curl | jq - "Let me use or
sedto transform this"awk - "Bash loop with grep/sed will handle this"
- "This is a simple one-liner"
- "jq is purpose-built for JSON"
All of these mean: Write a jbang script instead.
如果你有以下任何一种想法,立刻停下来,改为编写jbang脚本:
- "我要用来解析这个JSON"
jq - "一个简单的管道就能搞定"
curl | jq - "我用或者
sed来转换这个内容"awk - "带grep/sed的Bash循环就能处理"
- "这就是个简单的单行命令"
- "jq就是专门为JSON打造的"
以上所有情况都意味着:你应该编写jbang脚本。
When to Use JBang vs Bash
JBang与Bash使用场景对比
dot
digraph tool_choice {
"Automation task?" [shape=diamond];
"Simple file/git operation?" [shape=diamond];
"Use Bash" [shape=box];
"Use JBang" [shape=box];
"Automation task?" -> "Simple file/git operation?" [label="yes"];
"Automation task?" -> "Use Bash" [label="no"];
"Simple file/git operation?" -> "Use Bash" [label="yes"];
"Simple file/git operation?" -> "Use JBang" [label="no"];
}Use JBang for:
- JSON/XML parsing and transformation
- REST API calls and processing
- Data extraction and formatting
- Multi-step file processing
- Anything requiring logic beyond simple filters
- Scripts you might need to debug or extend
Still use Bash for:
- Git commands (,
git status)git commit - Simple file operations (,
ls,cp)mv - System tools (,
chmod)mkdir - One-off glue commands
dot
digraph tool_choice {
"Automation task?" [shape=diamond];
"Simple file/git operation?" [shape=diamond];
"Use Bash" [shape=box];
"Use JBang" [shape=box];
"Automation task?" -> "Simple file/git operation?" [label="yes"];
"Automation task?" -> "Use Bash" [label="no"];
"Simple file/git operation?" -> "Use Bash" [label="yes"];
"Simple file/git operation?" -> "Use JBang" [label="no"];
}JBang适用场景:
- JSON/XML解析与转换
- REST API调用与处理
- 数据提取与格式化
- 多步骤文件处理
- 任何需要超出简单过滤器逻辑的场景
- 你可能需要调试或扩展的脚本
仍适合使用Bash的场景:
- Git命令(,
git status)git commit - 简单文件操作(,
ls,cp)mv - 系统工具调用(,
chmod)mkdir - 一次性粘合命令
Quick Reference
快速参考
| Task | ❌ Avoid | ✅ Prefer |
|---|---|---|
| Parse JSON API | | |
| Extract from JSON file | | JBang with type-safe POJOs |
| Transform data | | JBang with clear logic |
| Multiple file processing | Bash loops | JBang with Java NIO |
| 任务 | ❌ 不推荐 | ✅ 推荐 |
|---|---|---|
| 解析JSON API | | 搭配Jackson/Gson的 |
| 从JSON文件提取内容 | | 支持类型安全POJO的JBang |
| 数据转换 | | 逻辑清晰的JBang |
| 多文件处理 | Bash循环 | 使用Java NIO的JBang |
JBang Examples
JBang示例
JSON Processing
JSON处理
java
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS com.google.code.gson:gson:2.10.1
import com.google.gson.*;
import java.nio.file.*;
public class ExtractEmails {
record User(String name, String email, int age) {}
record UserData(User[] users) {}
public static void main(String[] args) throws Exception {
var json = Files.readString(Path.of(args[0]));
var data = new Gson().fromJson(json, UserData.class);
for (var user : data.users) {
if (user.age > 30) {
System.out.println(user.email);
}
}
}
}Run:
jbang ExtractEmails.java users.json > emails.txtBenefits over jq:
- Type safety (compile errors if structure changes)
- IDE autocomplete and debugging
- Clear variable names and logic
- Easy to extend (add validation, error handling)
java
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS com.google.code.gson:gson:2.10.1
import com.google.gson.*;
import java.nio.file.*;
public class ExtractEmails {
record User(String name, String email, int age) {}
record UserData(User[] users) {}
public static void main(String[] args) throws Exception {
var json = Files.readString(Path.of(args[0]));
var data = new Gson().fromJson(json, UserData.class);
for (var user : data.users) {
if (user.age > 30) {
System.out.println(user.email);
}
}
}
}运行命令:
jbang ExtractEmails.java users.json > emails.txt相比jq的优势:
- 类型安全(如果结构变化会触发编译错误)
- IDE自动补全与调试支持
- 清晰的变量名与逻辑
- 易于扩展(可添加校验、错误处理)
API Calls
API调用
java
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS com.google.code.gson:gson:2.10.1
import com.google.gson.*;
import java.net.http.*;
import java.net.URI;
import java.time.*;
import java.time.format.*;
public class GithubRelease {
record Release(String tag_name, String published_at) {}
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.github.com/repos/jbangdev/jbang/releases/latest"))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
var release = new Gson().fromJson(response.body(), Release.class);
var published = Instant.parse(release.published_at);
var formatter = DateTimeFormatter.ofPattern("MMMM dd, yyyy 'at' HH:mm 'UTC'");
System.out.println("Latest jbang Release Report");
System.out.println("----------------------------");
System.out.println("Tag: " + release.tag_name);
System.out.println("Published: " + formatter.format(published.atZone(ZoneOffset.UTC)));
}
}Run:
jbang GithubRelease.javaBenefits over curl+jq:
- Built-in HTTP client (no curl dependency)
- Type-safe date handling
- Readable formatting logic
- Easy to add headers, auth, error handling
java
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS com.google.code.gson:gson:2.10.1
import com.google.gson.*;
import java.net.http.*;
import java.net.URI;
import java.time.*;
import java.time.format.*;
public class GithubRelease {
record Release(String tag_name, String published_at) {}
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.github.com/repos/jbangdev/jbang/releases/latest"))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
var release = new Gson().fromJson(response.body(), Release.class);
var published = Instant.parse(release.published_at);
var formatter = DateTimeFormatter.ofPattern("MMMM dd, yyyy 'at' HH:mm 'UTC'");
System.out.println("Latest jbang Release Report");
System.out.println("----------------------------");
System.out.println("Tag: " + release.tag_name);
System.out.println("Published: " + formatter.format(published.atZone(ZoneOffset.UTC)));
}
}运行命令:
jbang GithubRelease.java相比curl+jq的优势:
- 内置HTTP客户端(无curl依赖)
- 类型安全的日期处理
- 可读性强的格式化逻辑
- 易于添加请求头、鉴权、错误处理
Common Rationalizations
常见辩解
| Excuse | Reality |
|---|---|
| "jq is purpose-built for JSON" | JBang with Gson/Jackson is MORE purpose-built - type-safe, debuggable |
| "Single command is simpler" | JBang scripts are just as easy: |
| "jq/curl are standard tools" | JBang is standard for Java devs, more maintainable long-term |
| "Bash is more efficient" | Slight overhead is worth type safety and debugging |
| "This is just a quick script" | Quick scripts become production code - start with quality |
| "I don't need type safety" | You discover you need it when the API changes |
| "I can solve this directly with jq" | You're trading short-term convenience for long-term pain |
| "jq is efficient for single operations" | JBang is efficient AND maintainable |
| "WebFetch + jq is simple" | JBang HttpClient is simpler and type-safe |
| "Minimizes tool calls" | JBang minimizes debugging time and maintenance burden |
| 借口 | 实际情况 |
|---|---|
| "jq是专门为JSON打造的" | 搭配Gson/Jackson的JBang针对性更强 - 类型安全、可调试 |
| "单条命令更简单" | JBang脚本同样简单: |
| "jq/curl是标准工具" | 对于Java开发者来说JBang是标准工具,长期可维护性更强 |
| "Bash效率更高" | 类型安全和调试能力带来的价值远高于微小的效率开销 |
| "这只是个快速编写的脚本" | 快速脚本最终会演变为生产代码 - 从一开始就保证质量 |
| "我不需要类型安全" | 当API结构变化时你就会发现你需要它 |
| "我可以直接用jq解决这个问题" | 你是在用短期便利换取长期麻烦 |
| "jq对单操作来说效率很高" | JBang兼顾效率和可维护性 |
| "WebFetch + jq很简单" | JBang HttpClient更简单且支持类型安全 |
| "可以减少工具调用" | JBang减少了调试时间和维护负担 |
Pattern: Creating JBang Scripts
模式:创建JBang脚本
- Create file with extension
.java - Add shebang:
///usr/bin/env jbang "$0" "$@" ; exit $? - Add deps:
//DEPS group:artifact:version - Write code: Regular Java with method
main() - Run:
jbang ScriptName.java args
No compilation step needed - jbang handles it transparently.
- 创建扩展名为的文件
.java - 添加shebang:
///usr/bin/env jbang "$0" "$@" ; exit $? - 添加依赖:
//DEPS group:artifact:version - 编写代码:带方法的常规Java代码
main() - 运行:
jbang ScriptName.java args
无需编译步骤 - jbang会透明处理编译过程。
When Bash is Still Right
仍适合使用Bash的场景
Don't overdo it. These stay in Bash:
git status && git diffmkdir -p dir && cd dirchmod +x script.sh- Calling system tools: ,
gh pr createdocker run
If the task is invoking a tool, use Bash.
If the task is processing data or logic, use JBang.
不要过度使用JBang,以下场景仍使用Bash:
git status && git diffmkdir -p dir && cd dirchmod +x script.sh- 调用系统工具:,
gh pr createdocker run
如果任务是调用工具,使用Bash。
如果任务是处理数据或逻辑,使用JBang。