我试过了
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).
Unix.create_process实际上调用fork并执行 an execvpe,它本身调用execv原语(在模块的 OCaml C 实现中Unix)。然后该函数调用cstringvect(模块实现的 C 端的辅助函数),它将 arg 参数转换为 C 字符串数组,最后一个条目设置为NULL. 然而,execve按照惯例(请参阅execve(2)linux 手册页),该数组的第一个条目是程序的名称:
argv 是传递给新程序的参数字符串数组。按照约定,这些字符串中的第一个应该包含与正在执行的文件关联的文件名。
第一个条目(或者更确切地说,它收到的副本)实际上可以由接收这些参数的程序更改,并通过ls、top等显示。