相关疑难解决方法(0)

进行系统调用,将stdout输出作为字符串返回

Perl和PHP用反引号做到这一点.例如,

$output = `ls`;
Run Code Online (Sandbox Code Playgroud)

返回目录列表.类似的函数system("foo")返回给定命令foo的操作系统返回码.我在谈论一个将foo打印返回到stdout的变体.

其他语言如何做到这一点?这个函数有一个规范名称吗?(我要用"反击";但也许我可以用"syslurp"硬币.)

language-agnostic terminology

16
推荐指数
11
解决办法
1万
查看次数

如何正确读取大型过程输出

关于如何从流程流中读取已经有一些 答案,但据我所知,它们不包括从以下流程中读取:

  • 在进行任何输出之前可能会运行很长时间
  • 在其生命周期结束时产生巨大的输出(超过流缓冲区可以容纳)
  • 运行时间不应超过给定的时间范围
  • 结果输出作为一个整体需要(长字符串)

因此,使用上述解决方案会导致浪费的进程周期,因为即使没有输出,循环也会尝试读取流,或者由于进程无法打印整个输出(由于完全缓冲)而导致解决方案无法终止输出处理程序在读取之前等待进程终止.

我目前的解决方案看起来像这样(灵感来自批量读取大文件的解决方案)

(defun control-process (process timeout)
  (sb-ext:with-timeout timeout
    (handler-case
      (do ((output-stream (sb-ext:process-output process))
           (string nil))
          ((and (equalp (sb-ext:process-status process) :exited)
            (equalp (peek-char nil output-stream nil :eof) :eof))
           (values string :exited))
        (cond 
          ((equalp (sb-ext:process-status process) :signaled)
           (error 'unexpected-process-finish :finish-status :signaled))
          ((equalp (sb-ext:process-status process) :stopped)
           (error 'unexpected-process-finish :finish-status :stopped)))
        (let ((seq (make-string (file-length output-stream))))
          (read-sequence seq output-stream)
          (setf string (concatenate 'string string seq))
          (sleep 1)))
     (sb-ext:timeout (err)
      (declare (ignore err))
      (values nil :timeout))
     (unexpected-process-finish …
Run Code Online (Sandbox Code Playgroud)

sbcl common-lisp

3
推荐指数
1
解决办法
620
查看次数