17

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

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

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

4 ответа4

24

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

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

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

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

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

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

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

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

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

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

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

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

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

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 {}

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

6

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

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

echo '{}'

и это.

echo {}

Если они выдают одинаковый результат, то ответ для вашей оболочки - да. Как уже отмечали другие, по крайней мере, в рыбе будет да, а в рыбе - нет. Вывод - это то, для чего вам следует обратиться к 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» «» «;»

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .