На Mac заключите шаблон с подстановочным знаком в одинарные кавычки, чтобы оболочка zsh по умолчанию не раскрывала его до запуска команды. Например, printf '%s\n' '*.csv' передает буквальный текст *.csv как один аргумент. Кавычки удаляются оболочкой; звездочка доходит до программы. Если программа сама использует шаблоны, она может интерпретировать эту звездочку впоследствии.

Почему подстановочный знак изменяется до запуска команды

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

Apple определяет zsh как оболочку по умолчанию в Терминале, хотя Mac можно настроить на использование другой оболочки. Руководство Apple по Терминалу объясняет выбор по умолчанию и способы его изменения. Приведенный ниже метод с одинарными кавычками подходит для zsh и Bash; если вы используете другую оболочку, сверьтесь с ее руководством, так как правила экранирования могут отличаться.

Использование одинарных кавычек для буквального подстановочного знака

Введите шаблон с подстановочным знаком внутри одинарных кавычек, сохраняя любые другие относящиеся к нему символы. Например:

printf '%s\n' '*.csv'

Выводом будет буквальный текст *.csv, независимо от того, содержит ли текущий каталог CSV-файлы. printf получает шаблон в качестве аргумента и выводит его; оболочка не раскрывает звездочку. Кавычки являются синтаксисом оболочки, поэтому они не включаются в аргумент. Руководство Apple по написанию сценариев оболочки объясняет, что одинарные кавычки отключают подстановку оболочки внутри заключенного текста. Apple: Flow Control, Expansion, and Parsing.

Это особенно важно, когда программа должна обработать шаблон самостоятельно. Например, в macOS утилита find может сопоставлять имена файлов с помощью шаблона, переданного параметру -name:

find . -type f -name '*.log'

Здесь оболочка передает *.log в find буквально; затем find применяет собственное сопоставление имен файлов к файлам внутри текущего каталога. Кавычки не позволяют оболочке заменить шаблон именами в текущем каталоге до того, как его сможет использовать find. Значение шаблона зависит от принимающей программы: кавычки оболочки управляют подстановками самой оболочки, а не тем, как программа интерпретирует свой аргумент.

Когда вместо этого использовать обратную косую черту

Для короткого шаблона обратная косая черта может защитить отдельный подстановочный знак вне кавычек:

printf '%s\n' \*.csv

Это также передает звездочку буквально. Одинарные кавычки часто легче читать, когда шаблон содержит несколько специальных символов, пробелы или скобки. Например, 'chapter [0-9]*.txt' предотвращает интерпретацию оболочкой скобок и подстановочного знака. Apple описывает экранирование обратной косой чертой и поведение одинарных кавычек в своем руководстве по написанию сценариев оболочки.

Распространенные ошибки экранирования

Двойные кавычки не защищают надежно каждый символ оболочки. Они предотвращают раскрытие подстановочных знаков в zsh, но все же разрешают определенные подстановки, включая переменные, такие как $name, и подстановку команд, такую как $(command). Для шаблона, который должен быть передан в точности так, как набран, используйте одинарные кавычки, если аргументу не требуется одна из этих подстановок.

Одинарная кавычка не может присутствовать внутри строки в одинарных кавычках в качестве обычного символа. Если сам шаблон содержит апостроф, закройте закавыченную часть, добавьте апостроф с помощью другого метода экранирования и снова откройте одинарные кавычки; Apple демонстрирует эту технику экранирования оболочки в своем руководстве. Для нестандартных шаблонов внимательно проверьте точную команду перед ее запуском.

Также различайте раскрытие командной оболочкой и поведение принимающей программы. Заключение *.log в кавычки не заставляет программу трактовать звездочку как обычный символ; это лишь гарантирует, что оболочка передаст ее без изменений. Такая утилита, как find -name, может интерпретировать ее как шаблон, в то время как другая команда может воспринять ее буквально. Проверяйте собственную документацию команды, когда это различие имеет значение.

Быстрая проверка перед нажатием клавиши Return

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

Источники