Spec-Zone.ru › Elisp

Создание асинхронного процесса

В этом разделе описывается, как создать асинхронный процесс. После создания асинхронного процесса он работает параллельно с Emacs, и Emacs может взаимодействовать с ним, используя функции, описанные в следующих разделах (см. Ввод в процессы, и см. Вывод из процессов). Обратите внимание, что взаимодействие с процессами является лишь частично асинхронным: Emacs отправляет и получает данные из процесса только при вызове этих функций.

Асинхронный процесс контролируется либо через pty (псевдотерминал), либо через канал. Выбор между pty и каналом осуществляется при создании процесса, по умолчанию на основе значения переменной process-connection-type (см. ниже). Если доступен, pty обычно предпочтительнее для процессов, видимых пользователю, как в режиме Shell, поскольку они позволяют управлять задачами (C-c, C-z и т. д.) между процессом и его дочерними процессами, а также потому, что интерактивные программы обрабатывают pty как терминальные устройства, тогда как каналы не поддерживают эти функции. Однако для подпроцессов, используемых программами Lisp для внутренних целей (т. е. взаимодействие пользователя с подпроцессом не требуется), где требуется обмен значительными объемами данных между подпроцессом и программой Lisp, часто лучше использовать канал, поскольку каналы более эффективны. Кроме того, общее количество pty ограничено на многих системах, и не стоит тратить их впустую.

Функция: make-process &rest args

Эта функция является основной низкоуровневой процедурой для запуска асинхронных подпроцессов. Она возвращает объект процесса, представляющий подпроцесс. По сравнению с более высокоуровневой функцией start-process, описанной ниже, она принимает ключевые аргументы, более гибкая и позволяет указать фильтры и сигналы процесса в одном вызове.

Аргументы args представляют собой список пар «ключ/значение». Пропуск ключа всегда эквивалентен указанию его значения nil. Вот значимые ключи:

:name name

Используйте строку name в качестве имени процесса; если процесс с таким именем уже существует, то name модифицируется (путем добавления «<1>» и т. д.) для уникальности.

:buffer buffer

Используйте buffer в качестве буфера процесса. Если значение равно nil, подпроцесс не ассоциируется с каким-либо буфером.

:command command

Используйте command в качестве командной строки процесса. Значение должно быть списком, начинающимся с имени исполняемого файла программы, за которым следуют строки, передаваемые программе в качестве аргументов. Если первый элемент списка равен nil, Emacs открывает новый псевдотерминал (pty) и связывает его ввод и вывод с buffer, не запуская никакой программы; остальные элементы списка в этом случае игнорируются.

:coding coding

Если coding — символ, он указывает кодировку, которая будет использоваться как для чтения, так и для записи данных из и в соединение. Если coding — пара (decoding . encoding), то decoding будет использоваться для чтения, а encoding — для записи. Кодировка, используемая для кодирования данных, записываемых в программу, также используется для кодирования аргументов командной строки (но не самой программы, имя которой кодируется как любое другое имя файла; см. file-name-coding-system).

Если coding равно nil, будут применяться правила по умолчанию для поиска кодировки. См. Стандартные кодировки.

:connection-type type

Инициализирует тип устройства, используемого для связи с подпроцессом. Возможные значения: pty для использования pty, pipe для использования канала или nil для использования значения по умолчанию, выведенного из значения переменной process-connection-type. Этот параметр и значение process-connection-type игнорируются, если для параметра :stderr указано значение отличное от nil; в этом случае тип всегда будет pipe. На системах, где pty недоступны (MS-Windows), этот параметр также игнорируется, и каналы используются безусловно.

:noquery query-flag

Инициализирует флаг запроса процесса до query-flag. См. Запрос перед выходом.

:stop stopped

Если указано, stopped должно быть nil; использование любого значения, отличного от nil, является ошибкой. Ключ :stop в противном случае игнорируется и сохраняется для совместимости с другими типами процессов, такими как процессы канала. Асинхронные подпроцессы никогда не запускаются в состоянии остановки.

:filter filter

Инициализирует фильтр процесса до filter. Если не указано, будет предоставлен фильтр по умолчанию, который можно переопределить позже. См. Функции фильтра.

:sentinel sentinel

Инициализирует сторожевой процесс до sentinel. Если не указано, будет использоваться сторожевой процесс по умолчанию, который можно переопределить позже. См. Сторожевые процессы.

:stderr stderr

Связывает stderr со стандартным потоком ошибок процесса. Значение, отличное от nil, должно быть либо буфером, либо процессом канала, созданным с помощью make-pipe-process, описанным ниже. Если stderr равно nil, стандартный поток ошибок смешивается со стандартным выводом, и оба отправляются в buffer или filter.

Если stderr — буфер, Emacs создаст процесс канала, процесс стандартного потока ошибок. Этот процесс будет иметь фильтр по умолчанию (см. Функции фильтра), сторожевой процесс по умолчанию (см. Сторожевые процессы) и кодировки по умолчанию (см. Стандартные кодировки). С другой стороны, он будет использовать query-flag в качестве флага запроса при завершении (см. Запрос перед выходом). Он будет ассоциирован с буфером stderr (см. Буферы процессов) и отправит свой вывод (который является стандартным потоком ошибок основного процесса) туда. Чтобы получить объект процесса для процесса стандартного потока ошибок, передайте буфер stderr в get-buffer-process.

Если stderr — процесс канала, Emacs будет использовать его как стандартный поток ошибок для нового процесса.

:file-handler file-handler

Если file-handler не nil, ищем обработчик имени файла для текущего буфера default-directory, и вызываем этот обработчик имени файла для создания процесса. Если такого обработчика нет, продолжаем как если бы file-handler было nil.

Исходный список аргументов, модифицированный с фактической информацией о соединении, доступен через функцию process-contact.

Текущий рабочий каталог подпроцесса устанавливается в значение текущего буфера default-directory, если это локальное значение (определяется unhandled-file-name-directory), или ~ в противном случае. Если вы хотите запустить процесс в удалённом каталоге, передайте :file-handler t в make-process. В этом случае текущий рабочий каталог — это локальная составляющая имени default-directory (определяется file-local-name).

В зависимости от реализации обработчика имени файла, может быть невозможно применить filter или sentinel к результату процесса. Аргумент :stderr не может быть процессом канала, обработчики имён файлов не поддерживают процессы канала для этого. Буфер в качестве аргумента :stderr принимается, его содержимое отображается без использования процессов канала. См. Функции фильтра, Сторожевые процессы и Приём вывода.

Некоторые обработчики имён файлов могут не поддерживать make-process. В таких случаях эта функция ничего не делает и возвращает nil.

Функция: make-pipe-process &rest args

Эта функция создаёт двунаправленный канал, который можно подключить к дочернему процессу. Это полезно с ключевым аргументом :stderr функции make-process. Функция возвращает объект процесса.

Аргументы args представляют собой список пар «ключ/значение». Пропуск ключа всегда эквивалентен указанию его значения nil.

Вот значимые ключи:

:name name

Используйте строку name в качестве имени процесса. Как и в случае с make-process, она при необходимости модифицируется для уникальности.

:buffer buffer

Используйте buffer в качестве буфера процесса.

:coding coding

Если coding — символ, он указывает кодировку, которая будет использоваться для чтения и записи данных из и в соединение. Если coding — пара (decoding . encoding), то decoding будет использоваться для чтения, а encoding — для записи.

Если coding равно nil, будут применяться правила по умолчанию для поиска кодировки. См. Стандартные кодировки.

:noquery query-flag

Инициализирует флаг запроса процесса до query-flag. См. Запрос перед выходом.

:stop stopped

Если stopped не nil, запустите процесс в состоянии остановки. В состоянии остановки процесс канала не принимает входящие данные, но вы можете отправлять исходящие данные. Состояние остановки устанавливается функцией stop-process и сбрасывается функцией continue-process (см. Сигналы процессам).

:filter filter

Инициализирует фильтр процесса до filter. Если не указано, будет предоставлен фильтр по умолчанию, который можно изменить позже. См. Функции фильтра.

:sentinel sentinel

Инициализирует сторожевой процесс до sentinel. Если не указано, будет использоваться сторожевой процесс по умолчанию, который можно изменить позже. См. Сторожевые процессы.

Исходный список аргументов, модифицированный с фактической информацией о соединении, доступен через функцию process-contact.

Функция: start-process name buffer-or-name program &rest args

Данная функция является оболочкой более высокого уровня над make-process, предоставляя интерфейс, аналогичный call-process. Она создаёт новый асинхронный подпроцесс и запускает указанную программу program в нём. Она возвращает объект процесса, представляющий новый подпроцесс в Lisp. Аргумент name задаёт имя для объекта процесса; как и в make-process, он изменяется при необходимости, чтобы сделать его уникальным. Буфер buffer-or-name — это буфер, который следует ассоциировать с процессом.

Если program равно nil, Emacs открывает новый псевдотерминал (pty) и связывает его ввод и вывод с buffer-or-name, не создавая подпроцесс. В этом случае остальные аргументы args игнорируются.

Остальные args — это строки, которые определяют аргументы командной строки для подпроцесса.

В примере ниже, первый процесс запускается и работает (точнее, дремлет) в течение 100 секунд (буфер вывода ‘foo’ создаётся немедленно). Между тем, второй процесс запускается и получает имя ‘my-process<1>’ для уникальности. Он вставляет вывод списка каталога в конец буфера ‘foo’, до завершения первого процесса. Затем он завершается, и сообщение об этом вставляется в буфер. Значительно позже, первый процесс завершается, и другое сообщение об этом вставляется в буфер.

(start-process "my-process" "foo" "sleep" "100")
     ⇒ #<process my-process>
(start-process "my-process" "foo" "ls" "-l" "/bin")
     ⇒ #<process my-process<1>>

---------- Buffer: foo ----------
total 8336
-rwxr-xr-x 1 root root 971384 Mar 30 10:14 bash
-rwxr-xr-x 1 root root 146920 Jul  5  2011 bsd-csh
…
-rwxr-xr-x 1 root root 696880 Feb 28 15:55 zsh4

Process my-process<1> finished

Process my-process finished
---------- Buffer: foo ----------
Функция: start-file-process name buffer-or-name program &rest args

Подобно start-process, эта функция запускает новый асинхронный подпроцесс, выполняющий program в нём, и возвращает его объект процесса.

Отличие от start-process заключается в том, что эта функция может вызывать обработчик имени файла, основанный на значении default-directory. Этот обработчик должен запускать program, возможно, на локальном хосте, а возможно, на удалённом хосте, соответствующем default-directory. В последнем случае, локальная часть default-directory становится рабочей директорией процесса.

Эта функция не пытается вызывать обработчики имён файлов для program или для остальных args. Поэтому, если program или любой из args используют синтаксис удалённого файла (см. Магические имена файлов), они должны быть преобразованы либо в имена файлов, относительные к default-directory, либо в имена, идентифицирующие файлы локально на удалённом хосте, выполнив их через file-local-name.

В зависимости от реализации обработчика имён файлов, может быть невозможно применить process-filter или process-sentinel к получившемуся объекту процесса. См. Функции-фильтры и Сторожевые флаги.

Некоторые обработчики имён файлов могут не поддерживать start-file-process (например, функция ange-ftp-hook-function). В таких случаях эта функция ничего не делает и возвращает nil.

Функция: start-process-shell-command name buffer-or-name command

Эта функция похожа на start-process, за исключением того, что она использует оболочку для выполнения указанной команды command. Аргумент command — это строка командной оболочки. Переменная shell-file-name определяет, какую оболочку использовать.

Суть запуска программы через оболочку, а не непосредственно с помощью make-process или start-process, заключается в том, что вы можете использовать возможности оболочки, такие как подстановки в аргументах. Следовательно, если вы включаете любые произвольные пользовательские аргументы в команду, вы должны сначала заключить их в shell-quote-argument, чтобы любые специальные символы оболочки не имели своего специального значения в оболочке. См. Аргументы оболочки. Конечно, при выполнении команд на основе пользовательского ввода вы также должны учитывать последствия для безопасности.

Функция: start-file-process-shell-command name buffer-or-name command

Эта функция похожа на start-process-shell-command, но использует start-file-process внутри. Благодаря этому, command также может выполняться на удалённых хостах, в зависимости от default-directory.

Переменная: process-connection-type

Эта переменная управляет типом устройства, используемого для связи с асинхронными подпроцессами. Если она не равна nil, то используются ptys, если доступны. В противном случае используются каналы.

Значение process-connection-type вступает в силу при вызове make-process или start-process. Таким образом, вы можете указать, как общаться с одним подпроцессом, привязав переменную к вызову этих функций.

Обратите внимание, что значение этой переменной игнорируется при вызове make-process со значением nil параметра :stderr; в этом случае Emacs будет общаться с процессом с помощью каналов. Оно также игнорируется, если ptys недоступны (MS-Windows).

(let ((process-connection-type nil))  ; use a pipe
  (start-process …))

Чтобы определить, получил ли данный подпроцесс канал или pty, используйте функцию process-tty-name (см. Информация о процессе).

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

Spec-Zone.ru

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