子进程输出到Racket中的字符串



如何在Racket中实现以下过程:

(command->string "printf" "hello world")

以这样的方式:

  • 它在子流程中运行argv[]'("printf" "hello world"),在PATH中查找printf
  • 如果子进程退出时代码为零,则以字符串形式返回stdout
  • 如果子流程退出为非零,则引发异常
  • Stdin和stderr被忽略;它们与Racket过程相同

您可以使用

(with-output-to-string
(lambda ()
(or (system* (find-executable-path "printf") "hello world")
(error 'who "command failed"))))

如果您在Racket REPL上尝试此操作,它会起作用,但似乎会混淆REPL,并且不会显示下一个提示。我认为printf命令可能在窥探stdin,或者XREPL中有一个错误。用包裹上面的表达式

(parameterize ((current-input-port (open-input-string ""))) _)

似乎解决了这个问题。

(define (command->string command . args)
(let-values (((sub stdout stdin stderr)
(apply subprocess #f
(current-input-port)
(current-error-port)
(find-executable-path command)
args)))
(let ((output (port->string stdout)))
(subprocess-wait sub)
(if (eqv? 0 (subprocess-status sub))
output
(error "Command failed:" (cons command args))))))
(writeln (command->string "printf" "%s" "hello world"))

如果Racket的任何人正在阅读,请考虑在标准库中添加这样的内容。这很简单,而且通常需要。

最新更新