简而言之,我想抽象一下这个shebang,这样我就可以将其复制并粘贴到其他.ML文件中,而不必每次都指定文件名:
#!/usr/bin/env ocamlscript -o hello
print_endline "Hello World!"
我意识到我可以删除-o hello
位,但我希望所有二进制文件都有UNIX名称(hello
),而不是Windows名称(hello.ml.exe
)。< / p>
你需要一个复杂的shebang才能做到这一点。具有所需行为的Clojure示例:
":";exec clj -m `basename $0 .clj` $0 ${1+"$@"}
":";exit
Clojure是基于Java的,这就是为什么clj
需要文件的基名(something
而不是something.clj
)的原因。为了获得基本名称,你需要一个多行的shebang,因为单行shebang只能处理一个简单的静态命令行参数。为了做多行的shebang,你需要一个同时的语法:
有没有人知道OCaml欺骗这样做?我试过以下但没有成功:
(*
exec ocamlscript -o `basename $0 .ml` $0 ${1+"$@"}
exit
*)
let rec main = print_endline "Hello World!"
答案 0 :(得分:5)
你正在寻找的是一个shell和Objective Caml多语言(其中shell部分调用一个ocaml解释器来执行实际工作)。这是一个相对简单的问题。如果有必要,可以适应ocamlscript
,但我没有看到这一点。
#!/bin/sh
"true" = let exec _ _ _ = "-*-ocaml-*- vim:set syntax=ocaml: " in
exec "ocaml" "$0" "$@"
;;
(* OCaml code proper starts here *)
print_endline "hello"
答案 1 :(得分:2)
经过一些试验,我发现了这个shebang:
#!/bin/sh
"true" = let x' = "" in (*'
sh script here
*) x'
这是对Gilles提案的一种改进,因为它允许在OCaml评论中编写完整的shell脚本,而不会受到语法不兼容的困扰。
脚本必须终止(例如,使用exec
或exit
)而不会到达注释的末尾,否则将发生语法错误。这可以很容易地修复,但对于这种技巧的预期用途它并不是非常有用。
这是一个在OCaml端需要零运行时间开销的变体,但声明了一个新的类型名称(如果这很麻烦,请选择它任意复杂):
#!/bin/sh
type int' (*' >&- 2>&-
sh script here
*)
例如,这是一个用模块Str和Unix执行OCaml代码的脚本,也可以在传递参数--compile
时编译它:
#!/bin/sh
type int' (*' >&- 2>&-
if [ "$1" = "--compile" ]; then
name="${0%.ml}"
ocamlopt -pp 'sed "1s/^#\!.*//"' \
str.cmxa unix.cmxa "$name.ml" -o "$name" \
|| exit
rm "$name".{cm*,o}
exit
else
exec ocaml str.cma unix.cma "$0" "$@"
fi
*)
答案 2 :(得分:0)
我认为ocamlscript不支持这个。可能值得向作者提交功能请求,以允许自定义已编译二进制文件的扩展名,而无需指定完整输出基本名称。