Spec-Zone.ru › Elisp

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

После создания синхронного процесса Emacs ожидает его завершения, прежде чем продолжить работу. Примером служит запуск Dired в GNU или Unix: он запускает ls в синхронном процессе, а затем немного изменяет вывод. Поскольку процесс синхронный, весь список каталогов поступает в буфер до того, как Emacs пытается что-либо с ним сделать.

Пока Emacs ожидает завершения синхронного подпроцесса, пользователь может прервать ожидание, нажав C-g. Первое нажатие C-g пытается завершить подпроцесс сигналом SIGINT, но Emacs ожидает фактического завершения подпроцесса, прежде чем прервать ожидание. Если за это время пользователь нажмёт C-g ещё раз, подпроцесс будет немедленно завершён сигналом SIGKILL, а ожидание прервётся (кроме MS-DOS, где завершение других процессов не работает). См. раздел Прерывание.

Функции синхронных подпроцессов возвращают сведения о том, как завершился процесс.

Вывод синхронного подпроцесса обычно декодируется с использованием системы кодирования, подобно тексту, прочитанному из файла. Ввод, отправляемый подпроцессу функцией call-process-region, кодируется с использованием системы кодирования, подобно тексту, записываемому в файл. См. раздел Системы кодирования.

Функция: call-process program &optional infile destination display &rest args

Эта функция вызывает program и ожидает его завершения.

Текущий рабочий каталог подпроцесса устанавливается в значение default-directory текущего буфера, если эта переменная локальна (согласно проверке unhandled-file-name-directory), и в "~" в противном случае. Чтобы запустить процесс в удалённом каталоге, используйте process-file.

Стандартный ввод нового процесса берётся из файла infile, если infile не равен nil, и из нулевого устройства в противном случае. Аргумент destination задаёт, куда помещать вывод процесса. Возможны следующие варианты:

буфер

Вставить вывод в этот буфер перед точкой. Сюда входят как поток стандартного вывода, так и поток стандартной ошибки процесса.

имя буфера (строка)

Вставить вывод в буфер с этим именем перед точкой.

t

Вставить вывод в текущий буфер перед точкой.

nil

Отбросить вывод.

0

Отбросить вывод и немедленно вернуть nil, не дожидаясь завершения подпроцесса.

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

MS-DOS не поддерживает асинхронные подпроцессы, поэтому этот вариант там не работает.

(:file file-name)

Записать вывод в указанный файл, перезаписав его, если он уже существует.

(real-destination error-destination)

Не объединять потоки стандартного вывода и стандартной ошибки: обработать обычный вывод в соответствии с real-destination, а вывод ошибок — в соответствии с error-destination. Если error-destination равен nil, вывод ошибок отбрасывается; t означает объединение его с обычным выводом, а строка задаёт имя файла, в который перенаправляется вывод ошибок.

Нельзя напрямую указать буфер, в который следует поместить вывод ошибок: это слишком сложно реализовать. Однако этого результата можно добиться, направив вывод ошибок во временный файл, а затем вставив этот файл в буфер после завершения подпроцесса.

Если display не равен nil, то call-process перерисовывает буфер по мере вставки вывода. (Однако если для декодирования вывода выбрана система кодирования undecided, то есть кодировка определяется по фактическим данным, перерисовка иногда не может продолжаться после появления символов, отличных от ASCII. Существуют фундаментальные причины, из-за которых эту проблему трудно устранить; см. раздел Получение вывода от процессов.)

В противном случае функция call-process не перерисовывает буфер, и результаты становятся видимыми на экране только при обычной перерисовке этого буфера в Emacs.

Остальные аргументы, args, — это строки, задающие аргументы командной строки для программы. Каждая строка передаётся программе program как отдельный аргумент.

Возвращаемое значение call-process (если не было указано не ждать) указывает причину завершения процесса. Число задаёт код завершения подпроцесса: 0 означает успех, любое другое значение — неудачу. Если процесс завершился по сигналу, call-process возвращает строку с описанием сигнала. Если было указано, чтобы call-process не ожидала завершения, она возвращает nil.

В приведённых ниже примерах текущим является буфер «foo».

(call-process "pwd" nil t)
     ⇒ 0

---------- Buffer: foo ----------
/home/lewis/manual
---------- Buffer: foo ----------
(call-process "grep" nil "bar" nil "lewis" "/etc/passwd")
     ⇒ 0

---------- Buffer: bar ----------
lewis:x:1001:1001:Bil Lewis,,,,:/home/lewis:/bin/bash

---------- Buffer: bar ----------

Вот пример использования call-process, который ранее встречался в определении функции insert-directory:

(call-process insert-directory-program nil t nil switches
              (if full-directory-p
                  (concat (file-name-as-directory file) ".")
                file))
Функция: process-file program &optional infile buffer display &rest args

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

Аргументы обрабатываются почти так же, как в call-process, со следующими отличиями:

Некоторые обработчики имён файлов могут не поддерживать все комбинации и формы аргументов infile, buffer и display. Например, некоторые обработчики имён файлов могут вести себя так, будто display равен nil, независимо от фактически переданного значения. Другой пример: некоторые обработчики имён файлов могут не поддерживать разделение стандартного вывода и вывода ошибок с помощью аргумента buffer.

Если вызывается обработчик имени файла, он определяет запускаемую программу на основе первого аргумента program. Например, предположим, что вызывается обработчик удалённых файлов. Тогда путь, используемый для поиска программы, может отличаться от exec-path.

Второй аргумент infile может вызвать обработчик имени файла. Этот обработчик может отличаться от обработчика, выбранного для самой функции process-file. (Например, default-directory может находиться на одном удалённом узле, а infile — на другом. Или default-directory может быть обычным, а infile — находиться на удалённом узле.)

Если buffer — это список вида (real-destination error-destination), а error-destination задаёт файл, то применимы те же замечания, что и для infile.

Остальные аргументы (args) передаются процессу без изменений. Emacs не обрабатывает имена файлов, присутствующие в args. Чтобы избежать неоднозначности, лучше не использовать в args абсолютные имена файлов, а указывать все имена файлов относительно default-directory. Функция file-relative-name полезна для создания таких относительных имён файлов. Также можно использовать file-local-name (см. раздел Придание некоторым именам файлов «магических» свойств), чтобы получить абсолютное имя файла с точки зрения удалённого узла.

Переменная: process-file-side-effects

Эта переменная указывает, изменяет ли вызов process-file удалённые файлы.

По умолчанию эта переменная всегда имеет значение t, то есть вызов process-file потенциально может изменить любой файл на удалённом узле. Если переменной присвоено значение nil, обработчик имени файла может оптимизировать свою работу с учётом кэширования атрибутов удалённых файлов.

Изменять эту переменную следует только с помощью let-привязки; никогда не используйте setq.

Пользовательский параметр: process-file-return-signal-string

Этот пользовательский параметр указывает, возвращает ли вызов process-file строку с описанием сигнала, прервавшего удалённый процесс.

Если процесс возвращает код завершения больше 128, он интерпретируется как сигнал. process-file требует вернуть строку с описанием этого сигнала.

Поскольку существуют процессы, нарушающие это правило и возвращающие коды завершения больше 128, не соответствующие сигналу, process-file всегда возвращает для удалённых процессов код завершения как натуральное число. Если задать для этого пользовательского параметра значение, отличное от nil, функция process-file будет интерпретировать такие коды завершения как сигналы и возвращать соответствующую строку.

Функция: call-process-region start end program &optional delete destination display &rest args

Эта функция отправляет текст от start до end в качестве стандартного ввода процессу, выполняющему program. Если delete не равен nil, отправленный текст удаляется; это полезно, когда destination равен t, чтобы вставить вывод в текущий буфер вместо входного текста.

Аргументы destination и display задают, что делать с выводом подпроцесса и следует ли обновлять отображение по мере поступления вывода. Подробности см. в приведённом выше описании call-process. Если destination — целое число 0, call-process-region отбрасывает вывод и немедленно возвращает nil, не дожидаясь завершения подпроцесса (это работает только при поддержке асинхронных подпроцессов, то есть не в MS-DOS).

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

Возвращаемое значение call-process-region аналогично возвращаемому значению call-process: nil, если было указано вернуть управление, не дожидаясь завершения; в противном случае — число или строка, указывающие, как завершился подпроцесс.

В следующем примере мы используем call-process-region для запуска утилиты cat, передавая ей в качестве стандартного ввода первые пять символов буфера «foo» (слово «input»). cat копирует стандартный ввод в стандартный вывод. Поскольку аргумент destination равен t, этот вывод вставляется в текущий буфер.

---------- Buffer: foo ----------
input∗
---------- Buffer: foo ----------
(call-process-region 1 6 "cat" nil t)
     ⇒ 0

---------- Buffer: foo ----------
inputinput∗
---------- Buffer: foo ----------

Например, команда shell-command-on-region использует call-shell-region примерно таким образом:

(call-shell-region
 start end
 command              ; shell command
 nil                  ; do not delete region
 buffer)              ; send output to buffer
Функция: call-process-shell-command command &optional infile destination display

Эта функция синхронно выполняет команду оболочки command. Остальные аргументы обрабатываются так же, как в call-process. Согласно старому соглашению о вызове после display можно было передавать любое количество дополнительных аргументов, которые объединялись с command; такая возможность по-прежнему поддерживается, но настоятельно не рекомендуется.

Функция: process-file-shell-command command &optional infile destination display

Эта функция похожа на call-process-shell-command, но внутри использует process-file. В зависимости от default-directory, command может выполняться также на удалённых узлах. Согласно старому соглашению о вызове после display можно было передавать любое количество дополнительных аргументов, которые объединялись с command; такая возможность по-прежнему поддерживается, но настоятельно не рекомендуется.

Функция: call-shell-region start end command &optional delete destination

Эта функция отправляет текст от start до end в качестве стандартного ввода подчинённой оболочке, выполняющей command. Эта функция похожа на call-process-region, но в качестве процесса используется оболочка. Аргументы delete, destination и возвращаемое значение аналогичны таковым у call-process-region. Обратите внимание, что эта функция не принимает дополнительных аргументов.

Если command задаёт оболочку (например, через shell-file-name), имейте в виду, что поведение разных оболочек при передаче команд через стандартный ввод зависит от оболочки и системы и потому непереносимо. Различия особенно заметны, когда область содержит более одной строки, то есть при передаче оболочке команд со встроенными символами новой строки. Поэтому программам на Lisp, использующим этот приём, потребуется форматировать текст в области в соответствии с ожиданиями оболочки.

Функция: shell-command-to-string command

Эта функция выполняет command (строку) как команду оболочки, а затем возвращает вывод команды в виде строки. Если command фактически содержит несколько команд, поведение зависит от вызываемой оболочки (для локальных команд она определяется с помощью shell-file-name). В частности, в MS-Windows разделителем команд не может быть символ новой строки; вместо него используйте «&&».

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

Эта функция запускает program, ожидает её завершения и возвращает вывод в виде списка строк. Каждая строка в списке содержит одну строку текста, выведенную программой; символы конца строки удаляются. Аргументы после program, args, — это строки, задающие аргументы командной строки, с которыми запускается программа.

Если program завершается с ненулевым кодом завершения, эта функция сигнализирует об ошибке.

Эта функция работает, вызывая call-process, поэтому вывод программы декодируется так же, как и для call-process.

Функция: process-lines-ignore-status program &rest args

Эта функция аналогична process-lines, но не сигнализирует об ошибке, если program завершается с ненулевым кодом завершения.

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/Synchronous-Processes.html

Spec-Zone.ru

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