[英]How to create a command-line executable in Clojure
我已经写在Clojure中的程序,并且我想执行它的命令行而对命令行(如具体调用Java java -jar
)。 我想要一个可执行文件,例如myprogram
,它接受任何参数并运行我的程序。 以下是一些可能使这更容易的事情:
java
并且java
在路径中,这是可以的。 我用一种方法走了很远的路,但我不得不怀疑是否有更好的方法。
仅供参考:我已经尝试过的
我将在下面描述我的方法,但任何答案都不需要遵循这种方法。
我所做的是创建一个名为makescript
的lein插件,它生成一个uberjar,base64对它进行编码,然后将它放在一个所谓的heredoc变量的Ruby脚本中,如下所示:
# ...ruby script...
BASE64_JAR = <<-JAR_BOUNDARY
# [...base64 encoded file here...]
JAR_BOUNDARY
然后,您应该能够运行ruby脚本。 它将获取BASE64_JAR变量,取消编码,将其放在临时文件中,并通过调用java -jar <filename>
执行它。
我使用这种方法的问题是Ruby的base64
库和Clojure的clojure.data.codec.base64
库似乎产生了不同的字符串来表示jar,而Clojure编码的字符串如果我没有解码到原始文件使用Ruby。 这可能与两种语言之间的字符串本身(与UTF-8相关?)的编码有关。 以下是说明断开连接的repl / irb会话:
repl=> (def jar-contents (slurp "../target/myproj-0.1.0-SNAPSHOT-002-standalone.jar"))
repl=> (count jar-contents) ;; => 9433328
repl=> (def a-str (String. (clojure.data.codec.base64/encode (.getBytes jar-contents)) "UTF-8"))
repl=> (count a-str) ;; => 23265576
irb> f = File.open("target/pwgen-0.1.0-SNAPSHOT-002-standalone.jar", "r").read()
irb> p f.length # => 9657639
irb> b = Base64.encode64(f)
irb> p b.length # => 13564973
请注意原始大小接近但不相同,但编码版本有很大不同。
虽然这很令人费解,但我想知道为什么会发生这种情况,我想我可以绕过这个问题,让makecript只生成uberjar并将路径传递给另一个Ruby脚本,然后将对其进行base64编码(后来解码,也使用Ruby)独立的JAR。 问题仍然存在:是否有更好,更简单的方法? 我错过了一些明显的东西,还是看起来真的那么难?
如果你真的想这样做,你可以对其进行uuencode :在bash可执行的JAR文件(或任何其他二进制文件),请参阅本为例shell脚本中嵌入一个可执行的二进制
听起来您只是尝试使用更清晰的语法从脚本引导您的应用程序。 这可能是最容易做到的:
创建一个名为myprogram
的新bash脚本:
#!/usr/bin/bash
# pass whatever command line args you have down through the script
java -jar myjar.jar
给它执行权限
chmod +x myprogram
运行
./myprogram (with whatever params)
如果你想摆脱./
你需要移动东西,以便你的PATH
拾取脚本。
. 请记住,您 。 这样做几乎会破坏首先使用jvm的目的。 你只是通过一个额外的间接层来调用它。
如何将clojure作为解释脚本运行。 创建一个名为mytest
的新文件:
#!/usr/bin/clojure
(print "hello world")
然后
chmod +x mytest
然后简单地运行它
./mytest
这有很多弊端。 这开始真的很慢。 这个简单的1衬里需要2秒才能运行! 你只会得到一个文件。 可能这仅对最简单的事情有用。 但是,如果您只是想快速做一些不是生产或测试的东西,这可能会很有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.