Проблема чтения аргументов командной строки в скрипте - PullRequest
4 голосов
/ 05 августа 2010

Я пытаюсь написать библиотеку, чтобы сделать что-то специфичное для домена. Я хотел бы добавить в эту библиотеку несколько сценариев, которые можно запускать прямо из командной строки.

Макет каталога:

+- project.clj
+- src/
|   +- my-lib.clj
|   +- my-lib/
|        +- my-sub-1.clj
+- scripts/
    +- run-command.sh

Файл src / my-lib.clj загружает файл my-lib / my-sub-1.clj:

(ns my-lib
  (:use [my-lib.my-sub-1])
)

Файл src / my-lib / my-sub-1.clj содержит функции, которые я хочу сделать доступными. Одна из этих функций называется «конвертировать» и принимает два аргумента: имя входного файла и имя выходного файла; он преобразует формат файла. Чтобы использовать это:

(convert "input-file.txt" "output-file.txt")

Функции (делать что-то интересное) и (конвертировать) в src / my-lib / my-sub-1.clj выглядят так:

(defn do-something-interesting
  [input-file output-file]
  (magic-happens-here input-file output-file))

(defn convert
  [args]
  (let [infile (first args)
        outfile (second args)]
    (do-something-interesting infile outfile)))

Моя цель на данный момент: создать скрипт «run-command.sh» в каталоге «scripts», который принимает два аргумента: имя входного файла и имя выходного файла. Должно быть возможно запустить скрипт с:

./run-command.sh input-file.txt output-file.txt

У меня действительно работает run-command.sh, если я жестко закодирую имена файлов в этом скрипте, используя функцию (делать что-то интересное) вместо (конвертировать). Я еще не смог прочитать из списка аргументов ...

Работающий скрипт run-command.sh:

#!/bin/sh 
java -cp "../lib/*":"../src":$CLASSPATH clojure.main -e "
(use '[my-lib my-sub-1])
(do-something-interesting "path-to-input-file" "path-to-output-file")
"

... но что не работает:

#!/bin/sh 
java -cp "../lib/*":"../src":$CLASSPATH clojure.main -e "
(use '[my-lib my-sub-1])
(convert *command-line-args*)
"

Я получаю ошибку:

Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :reader of protocol: #'clojure.contrib.io/Streams found for class: nil (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:5435)
at clojure.lang.Compiler.eval(Compiler.java:5386)
at clojure.core$eval.invoke(core.clj:2382)
at clojure.main$eval_opt.invoke(main.clj:235)
at clojure.main$initialize.invoke(main.clj:254)
at clojure.main$null_opt.invoke(main.clj:279)
at clojure.main$main.doInvoke(main.clj:354)
at clojure.lang.RestFn.invoke(RestFn.java:422)
at clojure.lang.Var.invoke(Var.java:369)
at clojure.lang.AFn.applyToHelper(AFn.java:165)
at clojure.lang.Var.applyTo(Var.java:482)
at clojure.main.main(main.java:37)
Caused by: java.lang.IllegalArgumentException: No implementation of method: :reader of protocol: #'clojure.contrib.io/Streams found for class: nil
at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:471)
at clojure.contrib.io$eval32$fn__33$G__23__38.invoke(io.clj:118)
at bioclojure.vcf$header.invoke(vcf.clj:22)
at bioclojure.vcf$column_header.invoke(vcf.clj:55)
at bioclojure.vcf$column_names.invoke(vcf.clj:61)
at bioclojure.vcf$vcf2tsv.invoke(vcf.clj:169)
at bioclojure.vcf$convert.invoke(vcf.clj:185)
at user$eval474.invoke(NO_SOURCE_FILE:3)
at clojure.lang.Compiler.eval(Compiler.java:5419)
... 11 more

Я пытался "использовать" файл clojure.contrib.io в самом файле сценария run-command.sh и в верхнем библиотечном файле my-lib.clj, но пока не повезло ...

Если бы кто-нибудь мог мне помочь, это было бы здорово.

Январь

Ответы [ 3 ]

3 голосов
/ 06 августа 2010

Вам следует рассмотреть возможность использования функции «gen-class» для обработки аргументов командной строки в скомпилированной функции Clojure / Java вместо оперативной оценки кода Clojure с помощью функции main / repl Clojures:

(ns commandline
  (:gen-class))

(defn -main [& args]
  (convert args))

Используйте lein jar , чтобы создать файл Jar вашего Приложения и передать аргументы командной строки в скрипте оболочки в основную функцию:

#!/bin/bash

java -cp "../lib/*":../YOURPROJECT.jar:$CLASSPATH commandline "$@"
1 голос
/ 05 августа 2010

Это потому, что вы не указываете аргументы cli. Вы должны позвонить java .... clojure.main some-script.clj a b c. Тогда a, b и c будут содержаться в *command-line-args*.

0 голосов
/ 05 августа 2010

Я нашел решение благодаря предложению котарака. В run-command.sh мне нужно ссылаться на аргументы, используя bash-way вместо clojure. И мне даже не нужна эта отдельная (конвертируемая) функция.

Как выглядит сценарий:

#!/bin/sh 
java -cp "../lib/*":"../src":$CLASSPATH clojure.main -e "
(use '[my-lib my-sub-1])
(convert *command-line-args*)
"

Как это должно выглядеть:

#!/bin/sh 
java -cp "../lib/*":"../src":$CLASSPATH clojure.main -e "
(use '[my-lib my-sub-1])
(do-something-interesting \"$1\" \"$2\")
"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...