Error reading argument commands in script

I am trying to write a library to do some domain specific things. I would like to add some scripts to this library that can be run directly from the command line.

Directory Layout:

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

The src / my-lib.clj file loads the my-lib / my-sub-1.clj file:

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

The src / my-lib / my-sub-1.clj file contains the functions that I want to make available. One of these functions is called "convert" and takes two arguments: the name of the input file and the name of the output file; it converts the file. To use it:

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

The functions (do something interesting) and (convert) to src / my-lib / my-sub-1.clj look like this:

 (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))) 

My goal at the moment is to create a script "run-command.sh" in the "scripts" directory that takes two arguments: the name of the input file and the name of the output file. It should be possible to run the script with:

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

I have a run-command.sh job if I hard code the file names in this script using the (do-something-interesting) function instead of (convert). I have not yet been able to read the argument list ...

The run-command.sh script command works:

 #!/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") " 

... but what does not work:

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

The error I am getting is:

 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 

I tried using the "ing" clojure.contrib.io in the script file run-command.sh file itself and in the top library file my-lib.clj, but so far no luck ..

If anyone can help me, it will be great.

January

+4
source share
3 answers

You should use the "gen-class" function to process the command line arguments in the compiled Clojure / Java function, instead on the fly, evaluating Clojure code with the main / repl Clojures function:

 (ns commandline (:gen-class)) (defn -main [& args] (convert args)) 

Use lein jar to create your application's jar file and pass command line arguments in the shell summary to the main function:

 #!/bin/bash java -cp "../lib/*":../YOURPROJECT.jar:$CLASSPATH commandline " $@ " 
+3
source

This is because you are not specifying cli arguments. You have to call java .... clojure.main some-script.clj abc . Then a, b and c will be contained in *command-line-args* .

+1
source

I found a solution thanks to the offer of kotarak. In run -command.sh, I need to access the arguments using bash -way instead of clojure. And I donโ€™t even need this separate (converting) function.

What the script looked like:

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

What it should look like:

 #!/bin/sh java -cp "../lib/*":"../src":$CLASSPATH clojure.main -e " (use '[my-lib my-sub-1]) (do-something-interesting \"$1\" \"$2\") " 
0
source

All Articles