Разница между '{}' и {} в команде поиска?


18

В документации я вижу использование обоих способов:

find . -type f -exec file '{}' \;

find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \

4
Конечно, похоже, что он не имеет ничего общего с командой find, и вместо этого имеет отношение к правильному цитированию вызываемой команды.
Zoredache

1
Попробуйте это с рыбой, а не с ударом.
Чарльз Даффи

Ответы:


24

Для bashоболочки '{}'и {}взаимозаменяемы. Это не относится ко всем оболочкам (таким как fish).

Помещение аргумента в одинарные кавычки явно указывает на то, что фигурные скобки должны быть отправлены find. В зависимости от использования оболочка bash иногда заменяет содержимое фигурных скобок.

Как видно ниже, bash не заменяет пустые скобки, и они передаются команде. Для findкоманды это не имеет значения.

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

$ echo '{1,3}'
{1,3}

4
Не имеет значения с Bash. Имеет значение с рыбой.
Чарльз Даффи

1
Я бы заменил " are interchangeable"на " are interchangeable in some shells, not in all of them. ALWAYS use the single quotes to make sure they get passed as-is to the find command"(хорошие привычки начинаются с того, что вы используете правильный путь, даже если вам случится (всегда?) Быть в системе, которая допускает неоднозначное)
Оливье Дюлак

9

Почти со всеми доступными интерпретаторами оболочки нет никакой разницы между '{}'и {}.

Одинарные кавычки обычно используются для защиты встроенной строки от замены чем-то другим, например:

  • 'a b' является одним параметром из трех символов, без кавычек, которые будут двумя параметрами из одного символа
  • '$b' буквально знак доллара, за которым следует буква b, без кавычек, которые бы содержали то, что содержит переменная b, и, возможно, ничего, если не установлено
  • '!!' являются буквальными восклицательными знаками без кавычек и с некоторыми интерактивными оболочками, они будут расширяться до последней команды в истории
  • '*' это буквенная звездочка, без кавычек она будет заменена списком не скрытых имен файлов в текущем каталоге.

Как ни стандарта POSIX , ни господствующих оболочек ( sh(Bourne), ksh, bash, ash, dash, zsh, csh, tcsh) расширить {}к чему - то еще, то кавычки не требуются.

Однако существует экзотическая оболочка с именем fish, которая раскрывается {}как пустая строка, например:

> ps -p %self
  PID TTY          TIME CMD
 5247 pts/1    00:00:00 fish
> echo a {} b '{}'
a  b {}

Это, вероятно, причина, по которой findдокументация GNU предлагает защитить {}от интерпретации с помощью кавычек или обратной косой черты.


9

Для большинства пользователей (особенно тех, кто использует оболочки POSIX), нет никакой разницы.

В соответствии с разделом «Пример» справочной страницы для GNU find:

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

Я думаю, что автор (ы) справочной страницы GNU ошибаются из-за осторожности, но я отмечаю, что не все примеры на их man-странице цитируют скобки. Эти примеры из официальной документации по GNU также не содержат цитирования.

В примерах из спецификации POSIX / Single UNIX фигурные скобки не указаны при использовании с -execопцией.

В оболочке POSIX расширение параметров происходит только тогда, когда в фигурные скобки заключены специальные параметры, но не с пустыми фигурными скобками .

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

Наконец, я попытался запустить find -exec ls -l {} \;в sh, dashи , tcshно ни одна из этих оболочек не расширялась {}во что - нибудь еще. Как уже отмечали другие, fishоболочка обрабатывает {}специально, но это не оболочка POSIX (что ее создатели и пользователи считают преимуществом). Это не делает никакого вреда процитировать брекеты , но ленивые машинисток , которые не используют оболочку рыбы не должны испытывать чувство вины опуская их.


они не ошибаются, они пытаются убедиться, что люди используют правильный путь (т.е. используют '{}'вместо {}), чтобы их оболочка отправляла {}команду find без интерпретации (как упоминалось выше @ Charles-Duffy, если вам случится использовать fish , он будет интерпретировать, {}но не будет '{}', так что вам нужно использовать последний на этой оболочке (и на некоторых других!). Поэтому всегда используйте, '{}'чтобы избежать укуса неоднозначности{}
Оливье Дюлак

6

Это зависит от синтаксиса вашей оболочки. Если сомневаетесь, повторяйте это!

Запустить это

echo '{}'

и это.

echo {}

Если они выдают одинаковый результат, то ответ для вашей оболочки - да. Как уже отмечали другие, по крайней мере, это будет да в bash и нет в рыбе. Вывод - это то, для чего вам следует обратиться к man-странице данной команды.


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

Как можно проверить с помощью этой немного более подробной команды echo (показывающей аргументы, заключенные в кавычки),

#!/bin/sh
for a in "$@"; do
    printf '«%s» ' "$a"
done
echo ''

набрав это в командной строке,

find 'My Documents and Settings' -type f -exec file {} \;

значит это bash:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»

и это в рыбе:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»

Как общий совет, это никогда не повредит цитировать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.