Spec-Zone.ru › Elisp

Аргументы командной оболочки

Программам на Lisp иногда нужно запускать командную оболочку и передавать ей команду, содержащую имена файлов, указанные пользователем. Такие программы должны поддерживать любые допустимые имена файлов. Однако командная оболочка обрабатывает некоторые символы особым образом, и если эти символы встречаются в имени файла, они могут привести к неправильной интерпретации команды. Для обработки таких символов используйте функцию shell-quote-argument:

Функция: shell-quote-argument argument &optional posix

Эта функция возвращает строку, которая представляет в синтаксисе командной оболочки аргумент с фактическим содержимым argument. Результат можно безопасно добавить к команде командной оболочки и передать командной оболочке для выполнения.

Точное поведение этой функции зависит от операционной системы. Функция рассчитана на работу с синтаксисом стандартной командной оболочки вашей системы; если вы используете нестандартную командную оболочку, эту функцию потребуется переопределить. См. раздел Рекомендации по безопасности.

;; This example shows the behavior on GNU and Unix systems.
(shell-quote-argument "foo > bar")
     ⇒ "foo\\ \\>\\ bar"

;; This example shows the behavior on MS-DOS and MS-Windows.
(shell-quote-argument "foo > bar")
     ⇒ "\"foo > bar\""

Вот пример использования shell-quote-argument для создания команды командной оболочки:

(concat "diff -u "
        (shell-quote-argument oldfile)
        " "
        (shell-quote-argument newfile))

Если необязательный аргумент posix не равен nil, для цитирования argument применяются правила POSIX для командной оболочки независимо от системной командной оболочки. Это полезно, если команда может выполняться на удалённом узле, где обычно требуется командная оболочка POSIX.

(shell-quote-argument "foo > bar" (file-remote-p default-directory))

Следующие две функции полезны для объединения списка отдельных строк аргументов командной строки в одну строку и разбиения строки на список отдельных аргументов командной строки. Эти функции предназначены главным образом для преобразования пользовательского ввода из минибуфера — строки Lisp — в список строковых аргументов, передаваемых в make-process, call-process или start-process, а также для преобразования таких списков аргументов в одну строку Lisp, отображаемую в минибуфере или области эха. Обратите внимание: если используется командная оболочка (например, при использовании call-process-shell-command), аргументы по-прежнему необходимо защищать с помощью shell-quote-argument; combine-and-quote-strings не предназначена для защиты специальных символов от обработки командной оболочкой.

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

Эта функция разбивает string на подстроки, учитывая двойные и одинарные кавычки, а также экранирование обратной косой чертой.

(split-string-shell-command "ls /tmp/'foo bar'")
     ⇒ ("ls" "/tmp/foo bar")
Функция: split-string-and-unquote string &optional separators

Эта функция разбивает string на подстроки в местах совпадения с регулярным выражением separators, как это делает split-string (см. раздел Создание строк); кроме того, она удаляет кавычки из подстрок. Затем функция формирует список подстрок и возвращает его.

Если separators не указан или равен nil, по умолчанию используется "\\s-+" — регулярное выражение, соответствующее одному или нескольким символам с синтаксисом пробельных символов (см. раздел Таблица классов синтаксиса).

Эта функция поддерживает два вида заключения в кавычки: заключение всей строки в двойные кавычки "…" и экранирование отдельных символов с помощью обратной косой черты «\». Последний способ также используется в строках Lisp, поэтому эта функция умеет обрабатывать и их.

Функция: combine-and-quote-strings list-of-strings &optional separator

Эта функция объединяет list-of-strings в одну строку, заключая каждую строку в кавычки при необходимости. Она также вставляет строку separator между каждой парой строк; если separator не указан или равен nil, по умолчанию используется " ". Функция возвращает полученную строку.

В list-of-strings в кавычки необходимо заключать строки, содержащие подстроку separator. Строка заключается в двойные кавычки "…". В простейшем случае, если вы составляете команду из отдельных аргументов командной строки, в кавычки будут заключены все аргументы, содержащие пробелы.

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

Функция: multiple-command-partition-arguments command arguments &optional shellp

Эта функция возвращает список последовательных частей arguments, представляющего собой список строк. command — строка или список строк, задающий команду, которую следует выполнить для arguments (если только shellp не равен nil; см. ниже), включая любые аргументы, которые необходимо передавать при каждом запуске команды. Выполнение команды, составленной из command и любой одной из возвращённых частей, не приведёт к превышению системного ограничения на максимальную суммарную длину команды и её аргументов.

Если необязательный аргумент shellp не равен nil, эта функция неявно добавляет shell-file-name и shell-command-switch в начало command (см. раздел Создание асинхронного процесса). Кроме того, в этом случае при разбиении на части функция учитывает дополнительную длину, занимаемую кавычками и пробелами.

В системах, где process-environment (см. раздел Окружение операционной системы) учитывается в ограничении длины командной строки, функция принимает это ограничение во внимание.

В следующем примере мы искусственно задаём небольшое ограничение на длину командной строки и указываем фиксированный process-environment для наглядности. Разбиение списка аргументов на два подсписка в возвращаемом значении означает, что выполнение cmd foo bar baz в этой гипотетической системе превысило бы системные ограничения и завершилось неудачей. Вызывающий код должен дважды выполнить cmd, по одному разу для каждой из двух частей: сначала cmd foo bar, а затем cmd baz.

(let ((system-type 'gnu/linux)
      (command-line-max-length 20)
      (process-environment '("BLAH=blah")))
  (multiple-command-partition-arguments "cmd" '("foo" "bar" "baz")))
     ⇒ (("foo" "bar") ("baz"))

Эта функция действует с запасом и не пытается свести число частей arguments к минимуму, поскольку для этого потребовалось бы много платформозависимой информации, а также сведения о кодировке, которые в настоящее время недоступны Lisp.

Переменная: command-line-max-length

Эта переменная содержит максимальную длину команды и её аргументов в данной системе, измеряемую в символах, как она используется функцией multiple-command-partition-arguments.

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/Shell-Arguments.html

Spec-Zone.ru

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