在Clojure中构建CLI脚本的常用/标准方法是什么?
在我看来,这种方法应该包括以下特征:
一种轻松处理参数的方法,stdin / out / err。
不需要花太多时间来启动(理想情况下有某种JIT),否则就会失去在一个人的外壳中将事情混在一起的目的。
此外,在没有设置项目的情况下(可能在全局范围内安装它们)期望一种简单的方法来包含一次性依赖项是合理的。
理想情况下,非常感谢提供解决方案使用的简单示例。有点相当于:
#!/bin/bash
echo "$@"
cat /dev/stdin
注意:我知道这个问题之前有点质疑here。但问题是不完整的,答案似乎没有达成共识,也没有达成共识的大部分解决方案。
答案 0 :(得分:3)
选项是Planck,它在MacOS和Linux上运行。它使用自托管的ClojureScript,具有快速启动功能,并以JavaScriptCore为目标。
它有一个很好的SDK并模仿Clojure中的一些你在ClojureScript中没有的东西,例如: ID DATES RATES
1 2014-07-01 0.02
1 2014-07-02 0.03
1 2014-07-03 0.04
1 2014-07-04 0.05
2 2014-07-01 0.02
2 2014-07-02 0.03
2 2014-07-03 0.04
2 2014-07-04 0.06
3 2014-07-02 0.03
3 2014-07-03 0.04
3 2014-07-04 0.05
类似于planck.io
。它支持通过clojure.java.io
/ tools.deps.alpha
加载依赖项。
回应deps.edn
就像以下一样简单:
stdin
并打印命令行参数:
(require '[planck.core :refer [*in* slurp]])
(print (slurp *in*))
...
(println *command-line-args*)
具有依赖关系的独立脚本(即非项目)的示例:the tree
command line tool in Planck。
有一点需要注意的是,普朗克并不支持使用npm依赖项。因此,如果您需要这些,请转到针对NodeJS的Lumo。
第三个选项是joker,它是用Go编写的Clojure解释器。
答案 1 :(得分:3)
现在有new CLI tooling,可以在不使用第三方工具的情况下创建独立的Clojure脚本。一旦有了clj
命令行工具installed,下面的脚本便应该可以正常工作。
就原始问题而言,这取决于任何libraries您:require
来处理命令行参数和系统输入/输出,与任何Clojure / JVM CLI程序一样好。我还没有对它进行基准测试,因此我不会对性能进行评论,但是如果它让您感到担心,请尝试一下一下,看看启动时间是否适合您。但我会说这在依赖项管理上得分很高,因为该脚本是完全独立的(除了clj
工具之外,该工具现在无论如何都是推荐的运行Clojure的方法)。
文件:~/bin/script.sh
#!/bin/sh
"exec" "clj" "-Sdeps" "{:deps,{hiccup,{:mvn/version,\"1.0.5\"}}}" "$0" "$@"
(ns my-script
(:require
[hiccup.core :as hiccup]))
(println
(hiccup/html
[:div
[:span "Command line args: " (clojure.string/join ", " *command-line-args*)]
[:span "Stdin: " (read-line)]]))
然后确保其可执行:
$ chmod +x ~/bin/script.sh
并运行它:
$ echo "stdin" | script.sh command line args
<div><span>Command line args: command, line, args</span><span>Stdin: stdin</span></div>
NB。这主要是一个shell脚本,它将第三行上的字符串视为要执行的命令。随后的执行将使用给定的参数运行clj
命令行工具,该工具将把这些字符串评估为字符串(无副作用),然后继续评估下面的Clojure代码。
还要注意,依赖关系被指定为第三行传递给clj
的映射。您可以阅读有关on the Clojure website的工作原理的更多信息。依存关系图中的标记由逗号分隔,Clojure将其视为空格,但大多数shell则不会。
感谢“ clojurians” Slack小组的#tools-deps频道上的好人,这个解决方案来了。
答案 2 :(得分:2)
我知道你要求非项目创建方法来实现这个目标,但由于这个特定的问题已经在我脑海中浮现了很长一段时间,我想我会投入另一种选择。
TLDR:跳转到下面的“创建可执行CLI命令”部分
我有一些相同的要求列表,就像你回过头来创建可执行jar文件一样。我不是通过java -jar myfile.jar
讨论可执行文件,而是直接执行自包含的uber-jar,就像使用任何其他二进制文件一样。
如果您阅读zip file specification(jar文件作为jar文件是一个zip文件),事实证明这实际上是可行的。简短版本是您需要:
chmod +x
超级jar文件(或者如果在Windows上,请检查可执行文件框)应该注意,这实际上是由zip文件规范支持的。这就是自解压zip文件等的工作原理以及生成的胖jar(在上面的过程之后)仍然是一个有效的jar文件和一个有效的zip存档。所有相关命令(例如java -jar
)仍然有效,文件现在也可以直接从命令行执行。
此外,遵循上述模式,还可以添加对drip jvm launcher等内容的支持,从而大大加快cli脚本的启动时间。
事实证明,大约一年前我开始研究这个问题时,最后一个重写jar文件元数据的库并不存在。不仅仅是在clojure中,而是在整个JVM上。这仍然让我大吃一惊:jvm上所有语言的中央部署单元都是jar文件,那里没有实际读取jar文件内部的库。实际的zip文件结构中的内部结构,而不仅仅是java的ZipFile和朋友的内容。
此外,我找不到一个用于clojure的库,它处理了zip文件规范以干净的方式所需的二进制结构。
解决方案:
java -jar
。 所以,您可以使用leiningen创建一个新的命令行clojure应用程序并使用以下命令运行它:
~> lein new cli-cmd mycmd
~> cd mycmd
~> lein bin
Compiling mycmd.core
Compiling mycmd.core
Created /home/mbjarland/tmp/clj-cmd/mycmd/target/mycmd-0.1.0-SNAPSHOT.jar
Created /home/mbjarland/tmp/clj-cmd/mycmd/target/mycmd-0.1.0-SNAPSHOT-standalone.jar
Creating standalone executable: /home/mbjarland/tmp/clj-cmd/mycmd/target/mycmd
Re-aligning zip offsets
~> target/mycmd
---- debug output, remove for production code ----
options {:port 80, :hostname "localhost", :verbosity 0}
arguments []
errors nil
summary
-p, --port PORT 80 Port number
-H, --hostname HOST localhost Remote host
--detach Detach from controlling process
-v Verbosity level; may be specified multiple times to increase value
-h, --help
--------------------------------------------------
This is my program. There are many like it, but this one is mine.
Usage: mycmd [options] action
Options:
-p, --port PORT 80 Port number
-H, --hostname HOST localhost Remote host
--detach Detach from controlling process
-v Verbosity level; may be specified multiple times to increase value
-h, --help
Actions:
start Start a new server
stop Stop an existing server
status Print a server's status
Please refer to the manual page for more information.
Error: invalid action '' specified!
命令的输出只是样板命令行解析,我已经添加到leiningen模板中。
自定义序言脚本位于boot/jar-preamble.sh
,它支持滴水。换句话说,如果你的路径上有滴水,生成的可执行文件将使用它,否则它将回退到内部启动超级jar的标准java -jar
方式。
命令行解析的源代码和cli app的代码按照正常情况存在于src目录下。
如果您想要黑客攻击,可以更改前导脚本并重新运行lein bin
,新的前导码将通过构建过程插入到您的可执行文件中。
另外需要注意的是,此方法仍然会java -jar
,因此您 需要在您的路径上使用java。
答案 3 :(得分:1)
考虑Lumo,一个专门为脚本设计的ClojureScript环境。
请注意,虽然它支持ClojureScript(JAR)和NPM依赖项,但依赖性支持为still under development。
答案 4 :(得分:0)
我编写了许多Clojure(JVM)脚本,并使用CLI-matic库https://github.com/l3nz/cli-matic/提取了大多数与命令行解析,帮助的创建和维护,错误等相关的样板文件。