5

Goal: produce a Clojure script which runs -main when run as ./script.clj.

The closest I've gotten is

#!/bin/bash
#(comment
exec clj -m `basename $0 .clj` ${1+"$@"}
exit
#)
(defn -main [args]
   (println args))

But Clojure doesn't allow non-Lisp code inside multline comments, and Clojure doesn't have Common Lisps's #| ... |# syntax.

mcandre
  • 22,868
  • 20
  • 88
  • 147
  • Out of curiosity, why doesn't `#!/usr/bin/clj -m` work? – sarnold Mar 08 '11 at 01:29
  • Still not seeing how this is different from your recent question http://stackoverflow.com/questions/5224548/does-clojure-have-an-equivalent-to-pythons-if-name-main, which was itself a duplicate of http://stackoverflow.com/questions/973106/what-is-the-clojure-equivalent-of-the-python-idiom-if-name-main. Is there something about Brian's very thorough response that doesn't work for you? – amalloy Mar 08 '11 at 01:46
  • 1
    First, Brian's response is no response at all. Just because something is not idiomatic does not mean it should be avoided. Second, Brian says nothing about multiline shebangs. – mcandre Mar 08 '11 at 01:56
  • 1
    Actually if something is not idiomatic there are two possibilities. The first possibility is that you're an unknown genius who's found something profoundly new and important that will change the way people think about programming in the language. The second is that you've missed some key notion or another and are doing things which are counter-productive or worse. I'll leave it to you to guess which of these two is more likely. – JUST MY correct OPINION Mar 08 '11 at 02:21
  • Shebangs are not new, but they are useful for writing programs with command line interfaces. – mcandre Mar 28 '11 at 07:03
  • @sarnold: You're on the right track, but the basename, exec, and quote-colon-quote-semicolon syntax is necessary for scripts that aren't on the classpath. I don't like having to set the classpath for every little script I write. – mcandre Mar 28 '11 at 07:08

2 Answers2

6

The syntax is obscure, but it works. From Wikibooks.

$ ./hello.clj Fred
Hello Fred!

":";exec clj -m `basename $0 .clj` ${1+"$@"}
":";exit

(ns hello
    (:gen-class))

(defn -main
    [greetee]
    (println (str "Hello " greetee "!")))
mcandre
  • 22,868
  • 20
  • 88
  • 147
  • 1
    I'm surprised the Clojure authors didn't try harder to make Clojure scripts fit in better. – sarnold Mar 28 '11 at 07:11
  • The Clojure community is anti-POSIX. How do I shebang? "Don't; Use clj." How do I manually compile? "Don't; use Leiningen." – mcandre Mar 30 '11 at 01:54
0

Since Clojure CLI became available, use

#! /usr/bin/env clj

(println "Hello World!")
Aleksei Sotnikov
  • 633
  • 4
  • 15