异步子进程的输出通常只在 Emacs 等待某类外部事件(如时间流逝或终端输入)时到达。有时在 Lisp 程序中,需要在特定位置显式允许输出到达,甚至等待某个进程的输出到来。
该函数允许 Emacs 读取进程的待处理输出,并将输出传递给对应的过滤器函数。如果 process 非 nil,函数会一直阻塞,直到从该进程接收到部分输出或进程关闭连接。
参数 seconds 与 millisec 用于指定超时时间:前者以秒为单位,后者以毫秒为单位,两者相加为总超时时间。即使没有子进程输出,accept-process-output 也会在超时后返回。
参数 millisec 已废弃(不应使用),因为 seconds 支持浮点数,可指定小数秒级等待。若 seconds 为 0,函数仅接收所有待处理输出而不等待。
如果 process 是一个进程,且参数 just-this-one 非 nil,则只处理该进程的输出,暂停其他进程的输出处理,直到从该进程收到输出或超时。若 just-this-one 为整数,还会禁止定时器运行。该功能通常不推荐使用,但在语音合成等特定应用中可能必需。
如果函数从 process(或任意进程,若 process 为 nil)获取到输出,则返回非 nil;即使进程已退出,只要对应连接仍有缓冲数据,也可能返回非 nil。若超时或连接在输出到达前关闭,则返回 nil。
如果进程的连接中存在缓冲数据,即使进程已退出,accept-process-output 仍可能返回非 nil。因此,下面这种循环:
;; 该循环存在 bug。 (while (process-live-p process) (accept-process-output process))
虽然通常能读取 process 的全部输出,但存在竞态条件:如果连接仍有数据而 process-live-p 已返回 nil,就可能丢失部分输出。更稳妥的写法如下:
(while (accept-process-output process))
如果你在调用 make-process 时传入了非 nil 的 stderr,则会创建一个标准错误进程。See 创建异步进程。这种情况下,等待主进程的输出并不会同时等待标准错误进程的输出。要确保接收完进程的全部标准输出与标准错误,可使用如下代码:
(while (accept-process-output process)) (while (accept-process-output stderr-process))
如果你向 make-process 的 stderr 参数传入了缓冲区,仍需要单独等待标准错误进程,示例如下:
(let* ((stdout (generate-new-buffer "stdout"))
(stderr (generate-new-buffer "stderr"))
(process (make-process :name "test"
:command '("my-program")
:buffer stdout
:stderr stderr))
(stderr-process (get-buffer-process stderr)))
(unless (and process stderr-process)
(error "Process unexpectedly nil"))
(while (accept-process-output process))
(while (accept-process-output stderr-process)))
只有当两处 accept-process-output 均返回 nil 时,才能确定进程已退出且 Emacs 已读取全部输出。
无法通过这种方式读取远程主机上运行进程的待处理标准错误输出。