Создание асинхронного процесса
В этом разделе описывается, как создать асинхронный процесс. После создания асинхронного процесса он работает параллельно с 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