繁体   English   中英

如何在Clojure中创建命令行可执行文件

[英]How to create a command-line executable in Clojure

我已经写在Clojure中的程序,并且我想执行它的命令行对命令行(如具体调用Java java -jar )。 我想要一个可执行文件,例如myprogram ,它接受任何参数并运行我的程序。 以下是一些可能使这更容易的事情:

  1. 假设安装了java并且java在路径中,这是可以的。
  2. 虽然适用于Windows的解决方案将是一个很好的解决方案,但您可以假设这一切都是在类似UNIX的操作系统(如Mac OS X或Ubuntu)上完成的。
  3. 在某种脚本中调用Java是可以的。
  4. 可以使用其他语言,例如Ruby,Python或Perl,用户可能已安装或未安装。 All-bash会很酷,因为我可以假设有人拥有它。
  5. 如果我必须使用某种工具来构建将要执行的二进制文件,这是可以的,但我不是在寻找希望使用GUI界面操作的.app或.exe文件(例如,Oracle的appbundler不是什么我在这里寻找)。

我用一种方法走了很远的路,但我不得不怀疑是否有更好的方法。

仅供参考:我已经尝试过的

我将在下面描述我的方法,但任何答案都不需要遵循这种方法。

我所做的是创建一个名为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秒才能运行! 你只会得到一个文件。 可能这仅对最简单的事情有用。 但是,如果您只是想快速做一些不是生产或测试的东西,这可能会很有用。

既然GraalVM已经成熟了一点,您可能需要考虑将应用程序编译为二进制可执行文件。

还有如何完成一个很好的教程在这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM