41.2 Аргументы командной строки

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

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

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

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

;; Этот пример показывает поведение в системах GNU и Unix.
(shell-quote-argument "foo > bar")
     ⇒ "foo\\ \\>\\ bar"

;; Этот пример показывает поведение в MS-DOS и 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))

Следующие две функции полезны для объединения списка отдельных строк аргументов командной строки в одну строку и разделения строки на список отдельных аргументов командной строки. Эти функции в основном предназначены для преобразования пользовательского ввода в minibuffer, строки Lisp, в список строковых аргументов, которые будут переданы в make-process, call-process или start-process, или для преобразования таких списков аргументов в одну строку Lisp для отображения в minibuffer или области вывода. Обратите внимание, что если задействована командная оболочка (например, при использовании 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 в качестве подстроки. Заключение строки в кавычки заключается в двойные кавычки "…". В самом простом случае, если вы конструируете команду из отдельных аргументов командной строки, каждый аргумент, содержащий встроенные пробелы, будет заключен в кавычки.