我试过了
let _ = Unix.create_process "ls" [||] Unix.stdin Unix.stdout Unix.stderr
在utop中,它会使整个事情崩溃。
如果我将其写入.ml
并编译并运行,它将使终端崩溃,我的ubuntu将引发系统错误。
但为什么?
答案 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}}等显示。