【问题标题】:Running script with `Lein run`and `Clojure -M` hang. Works in REPL使用“Lein run”和“Clojure -M”运行的脚本挂起。在 REPL 中工作
【发布时间】:2022-09-14 19:58:47
【问题描述】:
$ lein --version
Leiningen 2.9.10 on Java 17.0.4.1 OpenJDK 64-Bit Server VM
$ clojure -version
Clojure CLI version 1.11.1.1155
$ java -version
openjdk version "17.0.4.1" 2022-08-12
OpenJDK Runtime Environment (build 17.0.4.1+1)
OpenJDK 64-Bit Server VM (build 17.0.4.1+1, mixed mode)

我有一些非常我正在尝试运行的基本代码。

(use '[clojure.java.shell :only [sh]])
(defn -main [] (sh "echo" "Hello, World!"))
(-main)

在 REPL 中,这可预测地返回

{:exit 0, :out "Hello, World!\n", :err ""}

但是,当这是脚本的内容(逐字)时,clojure -M 就会挂起。取消对 ns 的注释并尝试将其作为一个带有 lein run 的项目运行会产生相同的行为。

我也试过 requires + :refer 并将其放入命名空间。我试过使用 (print (:out (sh "echo" "stuff"))) 显式打印标准输出。

我的项目.clj:

(defproject findbad "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :dependencies [[org.clojure/clojure "1.11.1"]]
  :source-paths ["."]
  :repl-options {:init-ns findbad}
  :main findbad)

和 .lein/profile.clj:

{:user {:plugins [
                  [lein-try "0.4.3"]
                  [flat-layout/lein-template "1.6.0"]
                  [simple-layout/lein-template "0.1.0"]]}}

我可以使用clojure -M 运行以下命令,但lein run -main 现在会抛出错误(改进?)。

(ns findbad
  (:gen-class))

(use '[clojure.java.shell :only [sh]])

(defn -main [] (print "Hello, World"))

(-main)
{:clojure.main/message
 "Execution error (ArityException) at user/eval140 (form-init17641850740462455309.clj:1).\nWrong number of args (1) passed to: findbad/-main\n",
 :clojure.main/triage
 {:clojure.error/class clojure.lang.ArityException,
  :clojure.error/line 1,
  :clojure.error/cause
  "Wrong number of args (1) passed to: findbad/-main",
  :clojure.error/symbol user/eval140,
  :clojure.error/source "form-init17641850740462455309.clj",
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type clojure.lang.Compiler$CompilerException,
    :message
    "Syntax error macroexpanding at (/tmp/form-init17641850740462455309.clj:1:74).",
    :data
    {:clojure.error/phase :execution,
     :clojure.error/line 1,
     :clojure.error/column 74,
     :clojure.error/source "/tmp/form-init17641850740462455309.clj"},
    :at [clojure.lang.Compiler load "Compiler.java" 7665]}
   {:type clojure.lang.ArityException,
    :message "Wrong number of args (1) passed to: findbad/-main",
    :at [clojure.lang.AFn throwArity "AFn.java" 429]}],
  :trace
  [[clojure.lang.AFn throwArity "AFn.java" 429]
   [clojure.lang.AFn invoke "AFn.java" 32]
   [clojure.lang.Var invoke "Var.java" 384]
   [user$eval140 invokeStatic "form-init17641850740462455309.clj" 1]
   [user$eval140 invoke "form-init17641850740462455309.clj" 1]
   [clojure.lang.Compiler eval "Compiler.java" 7194]
   [clojure.lang.Compiler eval "Compiler.java" 7184]
   [clojure.lang.Compiler load "Compiler.java" 7653]
   [clojure.lang.Compiler loadFile "Compiler.java" 7591]
   [clojure.main$load_script invokeStatic "main.clj" 475]
   [clojure.main$init_opt invokeStatic "main.clj" 477]
   [clojure.main$init_opt invoke "main.clj" 477]
   [clojure.main$initialize invokeStatic "main.clj" 508]
   [clojure.main$null_opt invokeStatic "main.clj" 542]
   [clojure.main$null_opt invoke "main.clj" 539]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]],
  :cause "Wrong number of args (1) passed to: findbad/-main",
  :phase :execution}}

我如何获得“错误数量的参数”?我没有将任何东西传递给一个不带任何东西的函数。

即使我能让那个 (print "Hello, World") 示例起作用,那也不是我感兴趣的。

编辑:好的,我不确定我做了什么不同,但我可以让它与(print (:out (sh "echo" "stuff")))一起工作。此外,悬挂已修复 (shutdown-agents)

【问题讨论】:

  • 你想用 clj-cli 或 lein 或两者一起工作吗?如果你想要lein,为什么不从例如开始呢? lein new app findbad,这基本上给了你一个理智的开始。为什么叫(-main)? main 的要点是你可以从构建工具调用,或者如果你构建了一个,则稍后通过 jar 调用。不鼓励在 ns 中使用顶级 use/require/... - 在 ns 中使用 :require
  • 我确实是从lein new开始的。我调用 main 是因为没有它,脚本在我运行它时什么也没做(我先做的)。我试过 :require in with ns,但是没有用。完全没有。
  • 注意 lein new xlein new app x 之间的区别 - 后者引导其他东西
  • 我明白你的意思,但我也有同样的行为。
  • 您执行 lein new app x && cd x && lein run 并打印出错误(看不到“Hello World”)?

标签: shell clojure echo


【解决方案1】:

您的主函数不接受任何参数 ([])。 Clojure 使用命令行参数列表从 cli 调用 -main 导致 arity 异常。尝试将 & args 添加到 -main 参数向量:

(defn -main [& args] (print "Hello, World"))

【讨论】:

  • 我懂了。我真傻。我正在尝试将“-main”作为 CLI 参数传递,不是吗?添加 & args 让我很高兴吃掉我的输入。或者我可以简单地不尝试传递任何东西。谢谢。
  • 您还可以从 -main 函数打印 args 并尝试带或不带参数的 lein runclojure -M 以查看 args 的内容。 (defn -main [& args] (pr args))
  • 我不确定你在说什么。我不是要打印参数。实际的脚本是为了收集一些信息,处理它,然后打印出来。
猜你喜欢
  • 2014-11-28
  • 1970-01-01
  • 2012-12-31
  • 1970-01-01
  • 2012-06-08
  • 1970-01-01
  • 2017-08-18
  • 2016-03-25
  • 2016-11-09
相关资源
最近更新 更多