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

Jac*_*ale 4 unix ocaml

我试过了

let _ = Unix.create_process "ls" [||] Unix.stdin Unix.stdout Unix.stderr
Run Code Online (Sandbox Code Playgroud)

在utop中,它会使整个事情崩溃.

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

但为什么?

小智 8

正确的方式是:

let pid = Unix.create_process "ls" [|"ls"|] Unix.stdin Unix.stdout Unix.stderr
Run Code Online (Sandbox Code Playgroud)

数组的第一个元素必须是"命令"名称.

在某些系统上/bin/ls是一个链接到一些更大的可执行文件,它将查看argv.(0)如何表现(cf Busbox); 所以你真的需要提供这些信息.

(您经常会看到/usr/bin/vi许多系统上的sym链接到哪个vim).


did*_*erc 5

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

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

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