найдите (1): как звездообразный подстановочный знак реализован, чтобы он перестал работать на некоторых именах файлов?

  1. Вы должны расположить с интервалами после if [ потому что [ на самом деле команда (как test) который читает, это - аргументы (это может быть интерпретировано оболочкой, но это может быть не). Используя [[ удостоверяется, что внутренняя логика оболочки используется (быстрее, так как никакой новый процесс не запускается). Хотя оболочки могут интерпретировать [ и test как builtins, эта функция может быть выключена с enable (и затем новый процесс действительно запускается).

  2. = оператор сравнения в условных выражениях (и внешний и встроенный) однако, это - также оператор присваивания в другом месте. В то время как test и = соответствуйте POSIX, с помощью == (распознанный в [[) кажется, разумный выбор каждый раз, когда каждый не стремится к соответствию POSIX, так как оно приносит немного больше исправности к несоответствию оболочки контекстно-зависимого значения =.

  3. exit 1 - почему эффективно отбрасывают возвращаемое значение редактора? Или пропустите его полностью или использование exec заменять сценарий редактором.


#!/bin/bash
editor=$1
if [[ "$1" == "g" ]]; then
    exec geany "$file.tex"
else
    linha=$(wc -l < "$file.tex")
    exec texstudio --line $linha  "$file.tex"
fi
32
10.04.2015, 01:07
2 ответа

Это действительно хороший улов. Из быстрого взгляда на исходный код для GNU найдите, я бы сказал, что это сводится к тому, как Fnmatch ведет себя на недействительных последовательностях байтов ( pred_name_common в PRED.C ):

b = fnmatch (str, base, flags) == 0;
(...)
return b;

Этот код тестирует возвращаемое значение fnmatch для равенства с 0, но не проверяет наличие ошибок; Это приводит к любым ошибкам, сообщаемыми как «не совпадают».

Было предложено, много лет назад, чтобы изменить поведение этой функции LIBC, чтобы всегда вернуть True на * шаблон, даже на разбитых именах файлов, но из того, что я могу сказать, идея должна были отклонены (см. Нить, начиная с https://sourceware.org/ml/mlibc-hacker/2002-11/msg-hacker/2002-11/msg00071.html ):

Когда Fnmatch обнаруживает неверный мультибайтный символ, он должен вернуться к Один байтовый сопоставление, так что «*» имеет шанс сопоставить такую ​​строку.

И почему это лучше или правильнее? Есть ли существующая практика?

, как упомянуто Стефана Чазелас в комментарии, а также в том же потоке 2002 года, это несовместимо с расширением GLOC, выполненным оболочками, которые не зависят от недопустимых символов. Возможно, еще более головоломки - это тот факт, что обратный тест будет соответствовать только те файлы, которые имеют разбитые имена (создают файлы в bash с Touch $ 'd \ 351marer' $ 'Touch \ 303 \ 251' $ '\ 346 \ 227 \ 245 \ 346 \ 234 \ 254 \ 350 \ 252 \ 236 '):

$ find -name '*'
.
./Touché
./日本語

$ find -not -name '*'
./D?marrer

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

26
27.01.2020, 19:37

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

Найти Использование FNMATCH fnmatch для проверки совпадения шаблон, чтобы вы могли использовать Ltrace , чтобы проверить результат:

$ touch $'\U1212'aa
$ touch D$'\351'sinstaller
$ LC_ALL=en_US.utf8 ltrace -e fnmatch find -name '*'          
find->fnmatch("foo", "foo", 0)                   = 0
find->fnmatch("Foo", "foo", 0)                   = 1
find->fnmatch("Foo", "foo", 16)                  = 0
find->fnmatch("*", ".", 0)                       = 0
.
find->fnmatch("*", "D\351sinstaller", 0)         = -1
find->fnmatch("*", "\341\210\222aa", 0)          = 0
./ሒaa
+++ exited (status 0) +++

с D \ 351SInstaller FNMATCH Возврат -1 , указал, что он не соответствует. Допустимый характер, такой как ሒ AA .

В вашем случае с NOTF-8 NATF-8 \ 351 \ 351 является недействительным символом, вызывая сбой шаблона.

13
27.01.2020, 19:37

Теги

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