Posix.Process.execp
을 사용하여 실행 한 명령의 출력을 캡처하려고합니다. stackoverflow 찾은 일부 C 코드를 포팅하고 한 실행에 대한 출력을 캡처 할 수 있지만 두 번째 실행 출력을 가져올 수 없습니다.SML에서 명령의 stdout 캡처
여기 내 함수의 :
(* Runs a command c (command and argument list) using Posix.Process.execp. *)
(* If we successfully run the program, we return the lines output to stdout *)
(* in a list, along with SOME of the exit code. *)
(* If we fail to run the program, we return the error message in the list *)
(* and NONE. *)
fun execpOutput (c : string * string list) : (string list * Posix.Process.exit_status option) =
let fun readAll() = case TextIO.inputLine TextIO.stdIn
of SOME s => s :: (readAll())
| NONE => []
(* Create a new pipe *)
val { infd = infd, outfd = outfd } = Posix.IO.pipe()
in case Posix.Process.fork()
of NONE => (
(* We are the child. First copy outfd to stdout; they will *)
(* point to the same file descriptor and can be used interchangeably. *)
(* See dup(2) for details. Then close infd: we don't need it and don't *)
(* want to block because we have open file descriptors laying around *)
(* when we want to exit. *)
(Posix.IO.dup2 { old = outfd, new = Posix.FileSys.stdout }
; Posix.IO.close infd
; Posix.Process.execp c)
handle OS.SysErr (err, _) => ([err], NONE))
| SOME pid =>
(* We are the parent. This time, copy infd to stdin, and get rid of the *)
(* outfd we don't need. *)
let val _ = (Posix.IO.dup2 { old = infd, new = Posix.FileSys.stdin }
; Posix.IO.close outfd)
val (_, status) = Posix.Process.waitpid (Posix.Process.W_CHILD pid, [])
in (readAll(), SOME status) end
end
val lsls = (#1 (execpOutput ("ls", ["ls"]))) @ (#1 (execpOutput ("ls", ["ls"])))
val _ = app print lsls
여기에 해당 출력입니다 :
[email protected]:/tmp/test$ ls
a b c
[email protected]:/tmp/test$ echo 'use "/tmp/mwe.sml";' | sml
Standard ML of New Jersey v110.79 [built: Tue Aug 8 16:57:33 2017]
- [opening /tmp/mwe.sml]
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[library $SMLNJ-BASIS/(basis.cm):basis-common.cm is stable]
[autoloading done]
a
b
c
val execpOutput = fn
: string * string list -> string list * ?.POSIX_Process.exit_status option
val lsls = ["a\n","b\n","c\n"] : string list
val it =() : unit
-
어떤 제안은 내가 잘못 무엇에?
감사합니다. Simon! strace를 통해 두 번째 자식이 파일 설명자 N에 글을 쓰고 부모의 표준 입력이 dup2에 의해 N으로 설정되었지만 부모가 두 번째로 실제로 어떤 메시지도 읽지 않는다는 것을 알았습니다. 나는 더 상세한 분석을 게시 할 것이고 나는 그것을 어떻게 고쳐야 할 것인가. –