在Clojure中构建CLI脚本的常用/标准方法问询
在Clojure中构建CLI脚本的常用方法
在Clojure生态里,确实有几个成熟的方案能完美匹配你提到的CLI脚本需求——不管是处理命令行参数、标准IO,还是追求启动速度、便捷引入依赖,我按实用性和贴合度给你整理一下:
1. Babashka(首选方案)
Babashka是目前Clojure脚本领域的标杆,完全满足你列出的所有特性:
- 基于GraalVM编译的Clojure子集,启动速度毫秒级,和Shell脚本几乎无差别;
- 原生支持
*command-line-args*、*in*/*out*/*err*等标准IO变量,处理参数和管道流非常轻松; - 支持全局安装,无需创建项目就能通过临时依赖或全局安装引入第三方库。
等效示例脚本
创建文件echo-stdin.clj:
#!/usr/bin/env bb ;; 打印所有命令行参数(用空格分隔) (println (apply str (interpose " " *command-line-args*))) ;; 读取并输出标准输入内容 (println (slurp *in*))
使用方式
- 给脚本添加执行权限:
chmod +x echo-stdin.clj - 运行测试:
# 直接传参数+管道输入 ./echo-stdin.clj hello world < some-input.txt
引入临时依赖
如果需要用到第三方库(比如cheshire处理JSON),无需创建项目,直接在运行时指定依赖:
bb -Sdeps '{:deps {cheshire/cheshire {:mvn/version "5.12.0"}}}' echo-stdin.clj
也可以全局安装依赖,之后脚本就能直接调用:bb install cheshire/cheshire
2. Clojure CLI + 临时依赖(适合完整Clojure语法)
官方的clj命令可以直接运行脚本,虽然启动速度比Babashka慢几秒,但能使用完整的Clojure语法和生态,适合需要复杂逻辑的脚本场景。
等效示例脚本
创建文件echo-stdin.clj:
#!/usr/bin/env clj ;; 打印命令行参数 (println (apply str (interpose " " *command-line-args*))) ;; 读取并输出标准输入 (println (slurp *in*))
使用方式
- 添加执行权限:
chmod +x echo-stdin.clj - 运行:
./echo-stdin.clj foo bar < input.txt
引入临时依赖
如果需要用cli-matic这类专业CLI参数解析库,运行时通过-Sdeps指定即可:
clj -Sdeps '{:deps {cli-matic/cli-matic {:mvn/version "0.5.2"}}}' -m myscript.core
3. GraalVM编译原生可执行文件(极致启动速度)
如果对启动速度有极致要求(和原生二进制一样快),可以用GraalVM把Clojure程序编译成独立可执行文件,适合需要频繁调用的工具。
步骤示例
- 创建源码文件
src/echo_stdin/core.clj:
(ns echo-stdin.core (:gen-class)) (defn -main [& args] ;; 打印命令行参数 (println (apply str (interpose " " args))) ;; 读取并输出标准输入 (println (slurp *in*)))
- 创建
deps.edn配置文件:
{:deps {} :aliases {:native {:main-opts ["-m" "clj.native-image"] :deps {org.clojure/tools.namespace {:mvn/version "1.4.4"} clj.native-image/clj.native-image {:mvn/version "0.1.0"}}}}}
- 编译成原生二进制:
clj -M:native echo-stdin
- 运行生成的可执行文件:
./echo-stdin hello < file.txt
方案选型总结
- Babashka:平衡易用性、启动速度和生态支持,是日常编写CLI脚本的首选;
- Clojure CLI:适合需要完整Clojure特性、能接受几秒启动时间的场景;
- GraalVM编译:适合对启动速度有极致要求、需要频繁调用的工具。
内容的提问来源于stack exchange,提问作者Jean Carlo Machado
相关产品推荐
相关产品推荐

