Создание асинхронного процесса
В этом разделе описывается, как создать асинхронный процесс. После создания асинхронный процесс выполняется параллельно с 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. Если type — это конс-ячейка(input . output), для стандартного ввода будет использоваться input, а для стандартного вывода (и стандартного потока ошибок, если:stderrравноnil) — output.В системах, где 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 в качестве буфера процесса. Если значение равно
nil, подпроцесс не связывается ни с одним буфером. :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, используются pty, если они доступны. В противном случае используются каналы.Значение
process-connection-typeприменяется при вызовеmake-processилиstart-process. Поэтому способ взаимодействия с отдельным подпроцессом можно задать, связав переменную на время вызова этих функций.Обратите внимание, что значение этой переменной игнорируется, если
make-processвызывается со значением параметра:stderr, отличным отnil; в этом случае Emacs будет взаимодействовать с процессом через каналы. Оно также игнорируется, если pty недоступны (MS-Windows).(let ((process-connection-type nil)) ; use a pipe (start-process ...))Чтобы определить, получил ли данный подпроцесс канал или pty, используйте функцию
process-tty-name(см. Сведения о процессах).
- Переменная: process-error-pause-time
Если в функции обработчика-сигнализатора или фильтра процесса возникает ошибка, Emacs (по умолчанию) приостанавливает работу на
process-error-pause-timeсекунд после отображения этой ошибки, чтобы пользователи успели ее увидеть. Однако при частом возникновении таких ошибок Emacs может перестать отвечать; это поведение можно отключить, установив дляprocess-error-pause-timeзначение 0.
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/Asynchronous-Processes.html