3

简而言之,我想抽象出这个 shebang,这样我就可以将它复制并粘贴到其他 .ML 文件中,而不必每次都指定文件名:

#!/usr/bin/env ocamlscript -o hello

print_endline "Hello World!"

我意识到我可以放弃这-o hello一点,但我希望所有二进制文件都具有 UNIX 名称 ( hello),而不是 Windows 名称 ( hello.ml.exe)。

你需要一个复杂的 shebang 来做到这一点。具有所需行为的 Clojure 示例:

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

Clojure 是基于 Java 的,这就是为什么clj需要文件的基本名称(something,而不是something.clj)。为了获得基本名称,您需要一个多行 shebang,因为单行 shebang 只能处理一个简单的静态命令行参数。为了做多行shebangs,你需要一个同时的语法:

  • 向 shell 发送 shell 命令
  • 隐藏主要语言的 shell 命令

有谁知道 OCaml 的诡计来做到这一点?我尝试了以下但没有成功:

(*
exec ocamlscript -o `basename $0 .ml` $0 ${1+"$@"}
exit
*)

let rec main = print_endline "Hello World!"
4

3 回答 3

7

您正在寻找的是一个外壳和目标 Caml 多语言(外壳部分调用 ocaml 解释器来执行实际工作)。这里有一个比较简单的。必要时适应使用ocamlscript,虽然我不明白这一点。

#!/bin/sh
"true" = let exec _ _ _ = "-*-ocaml-*- vim:set syntax=ocaml: " in
exec "ocaml" "$0" "$@"
;;
(* OCaml code proper starts here *)
print_endline "hello"
于 2011-09-29T23:26:13.367 回答
3

经过一些试验,我发现了这个shebang:

#!/bin/sh
"true" = let x' = "" in (*'
    sh script here
*) x'

这是对 Gilles 提议的一种改进,因为它允许在 OCaml 注释中编写完整的 shell 脚本,而不会受到语法不兼容的困扰。

脚本必须在没有到达注释末尾的情况下终止(例如,使用execor 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
*)
于 2015-02-27T15:42:15.550 回答
0

我不认为 ocamlscript 支持这一点。向作者提交功能请求以允许自定义已编译二进制文件的扩展名而不指定完整的输出基本名称可能是值得的。

于 2011-09-30T00:49:46.287 回答