如何在OCaml中使用Unix.create_process真正创建进程?

时间:2014-05-29 13:23:25

标签: unix ocaml

我试过了

let _ = Unix.create_process "ls" [||] Unix.stdin Unix.stdout Unix.stderr
在utop中,它会使整个事情崩溃。

如果我将其写入.ml并编译并运行,它将使终端崩溃,我的ubuntu将引发系统错误。

但为什么?

2 个答案:

答案 0 :(得分:7)

调用它的正确方法是:

let pid = Unix.create_process "ls" [|"ls"|] Unix.stdin Unix.stdout Unix.stderr

数组的第一个元素必须是“命令”名称。

在某些系统上/bin/ls是一个更大的可执行文件的链接,它会查看argv.(0)以了解如何操作(c.f。Busybox);所以你真的需要提供这些信息。

(您经常会看到/usr/bin/vi,现在许多系统上都是vim的sym链接。

答案 1 :(得分:4)

Unix.create_process实际上调用了fork,而execvpe执行了execv,它本身调用了Unix原语(在cstringvect模块的OCaml C实现中) 。 该函数然后调用NULL(模块实现的C端的辅助函数),它将arg参数转换为C字符串数组,最后一个条目设置为execve。但是,ls等按照惯例(参见execve(2) linux手册页)预期该数组的第一个条目是该程序的名称:

  

argv是传递给新程序的参数字符串数组。通过          约定,这些字符串中的第一个应该包含文件名          与正在执行的文件相关联

第一个条目(或者更确切地说,它收到的副本)实际上可以由接收这些参数的程序更改,并由top,{{1}}等显示。