Різниця між командами "{}" та {} у пошуку?


18

У документації я бачу використання обох способів:

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

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

4
Звичайно, схоже, що це не має нічого спільного з знаходженням, командою, а натомість має відношення до правильного цитування виклику команди.
Зоредаче

1
Спробуйте це з рибою, а не з баш.
Чарльз Даффі

Відповіді:


24

Для bashоболонки '{}'і {}є взаємозамінними. Це стосується не всіх оболонок (таких як fish).

Поміщення аргументу в єдині лапки прямо вказує на те, що фігурні дужки повинні бути надіслані find. Залежно від використання, оболонка bash іноді замінює вміст фігурних дужок.

Як видно нижче, bash не замінює порожні дужки, і вони передаються команді. Для findкоманди це не має значення.

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

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

4
Не має значення для Баша. Чи має значення риба.
Чарльз Даффі

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, якщо ви випадково використовуєте рибу , він буде тлумачити, {}але ні '{}', тому вам потрібно використовувати останнє на цій оболонці (і на кількох інших!). Тому завжди використовуйте, '{}'щоб не бути покусаним неоднозначністю{}
Олів'є Дулак

6

Це залежить від синтаксису вашої оболонки. Коли сумніваєтесь, відлунюйте це!

Виконати це

echo '{}'

і це.

echo {}

Якщо вони дають однаковий вихід, то відповідь для вашої оболонки - так. Як зазначали інші, це буде принаймні так у башті та ні у рибі. Вихід - це те, про що ви повинні проконсультуватися з певною сторінкою команди.


Якщо ви хочете стати в нагоді, ви навіть можете echoввести префікс до цілого командного рядка, щоб побачити фактичну команду з усіма її аргументами, що ваша оболонка насправді викликала б. Але остерігайтеся, що список, що містить аргументи команди плюс, є істинним масивом рядків, кожна, можливо, порожнім або з пробілом, але відлуння друкує його неоднозначно як розділений пробілом список.

Як можна підтвердити за допомогою цієї дещо більш багатослівної команди ехо (показує аргументи з цитатами guillemet),

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

ввівши це в командному рядку,

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

означає це, щоб бити:

«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.