Spec-Zone.ru › Elisp

Получение вывода от процессов

Вывод асинхронных подпроцессов обычно поступает только тогда, когда Emacs ожидает какое-либо внешнее событие, например истечение времени или ввод с терминала. Иногда в программе на Lisp полезно явно разрешить поступление вывода в определённый момент или даже дождаться вывода от процесса.

Функция: accept-process-output &optional process seconds millisec just-this-one

Эта функция позволяет Emacs читать ожидающий вывод от процессов. Вывод передаётся функциям фильтра, заданным для процессов (см. Функции фильтра процессов). Если process не равен nil, функция не возвращается, пока от process не поступит какой-либо вывод или пока process не закроет соединение.

Аргументы seconds и millisec позволяют задать время ожидания. Первый задаёт период в секундах, а второй — в миллисекундах. Указанные таким образом периоды времени складываются, и accept-process-output возвращается по истечении этого времени, даже если от подпроцесса не поступило никакого вывода.

Аргумент millisec устарел (и не должен использоваться), поскольку для задания ожидания в долях секунды аргумент seconds может быть числом с плавающей точкой. Если seconds равен 0, функция принимает весь ожидающий вывод, но не ждёт.

Если process является процессом, а аргумент just-this-one не равен nil, обрабатывается только вывод этого процесса, а вывод от других процессов приостанавливается до получения какого-либо вывода от этого процесса или истечения времени ожидания. Если just-this-one является целым числом, выполнение таймеров также блокируется. Обычно эта возможность не рекомендуется, но может быть необходима для определённых приложений, например синтеза речи.

Функция accept-process-output возвращает не-nil, если она получила вывод от process или от любого процесса, если process равен nil; это может произойти даже после завершения процесса, если соответствующее соединение содержит буферизованные данные. Функция возвращает nil, если истекло время ожидания или соединение было закрыто до поступления вывода.

Обратите внимание, что эта функция не гарантирует возврат сразу после того, как от подпроцесса станет доступен какой-либо вывод, поскольку основная цель функции — позволить Emacs читать вывод подпроцессов, а не свести время ожидания к минимуму. В частности, если process равен nil, не следует ожидать, что функция вернётся до истечения заданного времени ожидания. Поэтому, если программе на Lisp нужно свести к минимуму ожидание вывода подпроцесса, ей следует вызвать эту функцию, указав не-nil значение конкретного process.

Если соединение с процессом содержит буферизованные данные, accept-process-output может вернуть не-nil даже после завершения процесса. Поэтому, хотя следующий цикл:

;; This loop contains a bug.
(while (process-live-p process)
  (accept-process-output process))

часто считывает весь вывод из process, в нём есть состояние гонки, и часть вывода может быть пропущена, если process-live-p возвращает nil, пока соединение всё ещё содержит данные. Лучше написать цикл так:

(while (accept-process-output process))

Если при вызове make-process вы передали не-nil значение stderr, у процесса будет отдельный процесс для стандартного потока ошибок. См. Создание асинхронного процесса. В этом случае ожидание вывода основного процесса не ожидает вывода процесса стандартного потока ошибок. Чтобы убедиться, что получен весь вывод процесса как из стандартного потока вывода, так и из стандартного потока ошибок, используйте следующий код:

(while (accept-process-output process))
(while (accept-process-output stderr-process))

Если в аргумент stderr функции make-process был передан буфер, всё равно нужно дождаться процесса стандартного потока ошибок, например так:

(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 прочитал весь его вывод.

Таким способом невозможно прочитать ожидающий вывод стандартного потока ошибок процесса, выполняющегося на удалённом узле.

Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Accepting-Output.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API