Шаблон Bash для поиска каталогов, имена которых начинаются с точки (точка), путем "явного" соответствия, вместо использования "shopt -s dotglob"?

Поскольку вы просите о вставке в определенное место документа, сначала определите "определенное место" уникальной строкой. Я выбрал строку ##TIME## для следующего примера файла:

this is some text
Insert time here: ##TIME## <-- the time
this is some text

Эта команда sed вставит текущее время в позицию, отмеченную ##TIME##:

sed -i'.bak' 's/##TIME##/'"$(date +%r)"'/g' file

Результат:

this is some text
Insert time here: 09:37:05 PM <-- the time
this is some text
1
12.12.2016, 20:11
2 ответа

Прежде всего, я предполагаю, что вы знаете , что такое [b] , ? и * означают в шаблоне имени пути. (Если вы этого не сделаете, проведите дополнительное исследование.)

Рискуя повторить то, что сказали другие, вы слишком задумываетесь. Шаблоны, содержащие строку /. (т.е. / сразу , за которым следует . ) явно включают точку как буквальный символ. Дело в том, что [b] , ? и / или * , встречающиеся после . не влияет на то, может ли шаблон соответствовать точечным файлам. Последние три примера предлагаются в качестве примеров шаблонов (т. Е. Не просто простого файла / пути, , а чего-то, что потенциально может соответствовать нескольким файлам / pathnames - или none) , который будет соответствовать ~ / .bashrc - в отличие от первых двух, который будет соответствовать ~ /.bashrc , если . не обрабатывались специально.

Итак, каков ваш настоящий вопрос?

... Я пишу эти шаблоны для использования в файле конфигурации другой программы. Я хочу исключить пути, содержащие, например, «скрытые .git каталоги», и я не уверен , что у меня есть возможность указать dotglob в любом качестве.

Думаю, вы хотите что-то сделать (например, chown или cp ) со всеми файлами / каталогами , кроме тех, которые начинаются с точки. Но ваш код будет использоваться в чужом скрипте (с помощью команды . или source ), и вы боимся выполнять your_command * , потому что сценарий мог установить dotglob , поэтому * будет расширяться ко всем файлам, включая «скрытые». И вы не хотите отключать dotglob , потому что не хотите нарушать функциональность существующего скрипта.

  1. Используйте более умный подстановочный знак (шаблон расширения имени пути).

    Надеюсь, вы понимаете подстановочные знаки (также известные как globs) вроде [abc] - они соответствуют любому из символов a , b или c . Например, строка c [aou] t соответствует cat , cot и cut ; d [iou] g соответствует dig , dog и dug . (Они могут использоваться и обычно используются с диапазонами; например, [az] и [0-9] .) {{ 1}} Частным случаем этого является [! abc] - соответствует любому символу , кроме a , b или c . Таким образом, вы можете использовать [!.] * (или имя_каталога / [!.] * ) для сопоставления имен, начинающихся с символ, отличный от точки. Парадоксально, но [.] (в начале имени файла) не будет соответствовать точке, если dotglob не установлен, но [!.] будет исключить точку независимо от настройки dotglob .

    Это даст тот же результат, независимо от того, установлен ли dotglob или нет.

  2. Используйте dotglob (в подоболочке).

    Параметры оболочки ( shopt s) являются локальными для процесса,а атрибуты процесса никогда не перетекают в обратном направлении (вверх) от дочернего элемента к родительскому. Итак,

     (shopt -u dotglob;  your_command  *) 
    будет запускать your_command только для нескрытых файлов, {{ 1}}, не влияя на настройки и поведение остальной части скрипта.
  3. Используйте dotglob (без использования подоболочки).

    Некоторые люди предпочитают избегать подоболочек, потому что они используют дополнительные ресурсы. Но стоимость мизерная (если вы не делаете это в цикле, который выполняется много раз), , так что это не очень веская причина. Лучшая причина избегать подоболочки - это , если вам нужно сделать что-то, что влияет на среду оболочки, например cd или umask .

    В такой ситуации вы можете временно отключить dotglob , и позже восстановить предыдущую настройку.

    Если ввести shopt dotglob (без -s или -u ), сообщает (отображает) текущую настройку Опция dotglob . ( shopt with no parameters перечисляет текущие настройки всех параметров.) Он также соответственно устанавливает статус выхода. Флаг -q подавляет отображение, поэтому вы можете выполнить

     shopt -q dotglob 
    dotglob_setting = $? 
    shopt -u dotglob {{ 1}}  your_command  * 
    if ["$ dotglob_setting" = 0] 
    then 
    shopt -s dotglob 
    fi 

Но подождите… вы сказали «файл конфигурации другой программы». О чем ты говоришь? Если вы говорите о записи или изменении файла, в котором написано что-то вроде ignore = *.o , тогда весь этот вопрос не имеет смысла, потому что этот файл будет обрабатываться (и интерпретироваться) любой программой, обрабатывающей его, {{1} } и эта программа решит, как интерпретировать * - оболочка не имеет к этому никакого отношения.


Хорошо, теперь, когда мы лучше понимаем, в чем заключается вопрос:

Короткий ответ заключается в том, что поведение, которое вы наблюдаете, не имеет смысла. Если каталог .git существует, затем укажите его точно (буквально) как .git и укажите его с помощью подстановочного знака / Glob шаблон . [G] it должен вести себя идентично.

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

И, если он «использует оболочку», какую оболочку он использует? Во многих системах / bin / sh не является bash. Их базовое поведение в отношении шаблонов раскрытия имени пути (т. Е. Подстановочных знаков) должно быть таким же, но как только вы сойдете с крыльца, вы окажетесь в болоте. В спецификации POSIX для оболочки даже нет команды shopt , и (AFAIK) не могут сделать * развернуть до всех файлов (а не только не скрытых).

Если вы чувствуете, что зря тратят , потратив на это еще немного времени, вы можете поэкспериментировать с помещением / home / user / project / * в файл конфигурации Samhain и посмотреть, интерпретирует ли он его как все файлы или только как не скрытые. Если он интерпретирует его как все файлы, мы можем заключить, что

  1. Samhain не использует / bin / sh для расширения подстановочных знаков.
  2. Не используются стандартные правила по умолчанию для подстановочных знаков (те, которые вы так подробно обсуждали в своем вопросе).
  3. Документация неверна (или, в лучшем случае, неполна и вводит в заблуждение) , поскольку в ней говорится: «Шаблоны подстановочных знаков ('*', '?', '[...]') {{1 }}, как и в оболочке, для путей поддерживаются подстановки ». не говоря, что (в отличие от поведения оболочки по умолчанию) * означает все файлы.
  4. Он мог использовать bash в режиме dotglob для расширения подстановочных знаков. Но это не имеет смысла; как я уже сказал, обработка .git и . [G] it не соответствует нормальному поведению любой известной мне оболочки. У него почти наверняка есть собственный код для подстановочных знаков.

Но в любом случае я считаю, что мы можем с некоторой уверенностью сказать , что ваш вывод верен: в Samhain есть ошибка в отношении обработки подстановочных знаков в IgnoreAll ] технические характеристики. Возможно, вы захотите отправить поставщику отчет об ошибке. Или, поскольку вы нашли обходной путь, вы можете просто забыть об этом.

1
29.04.2021, 00:07

Когда шаблон используется для расширения имени файла, символ '.' В начале имени файла или сразу после косой черты должен быть соответствует явному совпадению, если не задана опция оболочки dotglob.

Это просто означает, что глобусы * , ? и [...] не соответствуют . в начале имени файла. Если вы хотите сопоставить . в начале имени файла, вы не можете использовать глобус, вы должны ввести . явно. Например:

$ echo ????
Work
$ echo .???
.gem .pki .ssh .vim

И чтобы ответить на ваш другой вопрос:

Как, в частности, поместить b в скобки после . сделать это "явным" совпадением в примере ~ /. [B] ashrc ?

Тот факт, что вы используете шаблон glob, не означает, что весь шаблон больше не является «явным». В ~ /. [B] ashrc , например, все символы /. Ashrc явно сопоставляются. Однако [b] является шаблоном glob, а также не является явным совпадением. (Технически ~ - это расширение тильды и выполняется раньше, чем расширение glob, поэтому это также явное совпадение.) Но другие символы, включая . , действительно соответствуют , поэтому ~ /. [B] ashrc соответствует ~ / .bashrc .

Для сравнения, ~ /? [B] ashrc не будет не соответствовать ~ / .bashrc , потому что . больше не сопоставляется явно.

7
29.04.2021, 00:07

Теги

Похожие вопросы