Використання вкладених дужок {} як аргументів командам та їх параметрам


11

Приклади

Нещодавно я знайшов приклади використання пар вкладених дужок {}, що не мають нічого середнього між дужками відкриття та закриття, як аргументи командам і навіть їх параметрам:

cat foo | xargs -I{} echo {}

find . -size 0 -exec rm -i {} \;

Відсутня документація

Моя проблема полягає в тому, що я не можу знайти документацію в посібнику з GNU Bash, яка описує використання {}в такому контексті, як у наведених вище прикладах.

Я не думаю, що це розширення параметрів , тому що знак долара повинен передувати вкладеним дужкам в розширенні параметра, як в ${}.

Це також не може бути розширенням дужок, оскільки воно має форму {x..y[..incr]}, де xі yне є необов'язковою.

Також це не може бути групуванням команд , оскільки {}використовується як аргументи.

Запитання

  1. Що взагалі означає пара, що додає дужки {}, як аргумент будь-якій команді, яка її приймає?

  2. Де я можу знайти документацію, яка описує використання {}аргументів?


У деяких командах є такі параметри {}- означає targetsдіяти, за допомогою findкоманди - це видалити / rmзнайти файли.
Туєн Фам

Відповіді:


16

Ці фігурні дужки башма залишають в спокої; вони належать findі xargs, відповідно, і описані у своїх довідкових сторінках.

man find

-exec командування ;

Виконати команду ; вірно, якщо статус 0 повернуто. Усі наступні аргументи для пошуку вважаються аргументами команди, поки аргумент, що складається з, не ;буде знайдений. Рядок {}замінюється поточним іменем файлу, який обробляється скрізь, коли він виникає в аргументах команди, а не тільки в аргументах, де він один, як у деяких версіях find. Обидві ці конструкції, можливо, знадобиться уникнути (з а \) або цитувати їх, щоб захистити їх від розширення оболонкою. Див. Розділ ПРИКЛАДИ для прикладів використання -execпараметра. Зазначена командазапускається один раз для кожного відповідного файлу. Команда виконується в початковому каталозі. Існують неминучі проблеми безпеки щодо використання -exec дії; ви повинні використовувати -execdirопцію замість цього.

-exec командування {} +

Цей варіант -execдії виконує задану команду на вибраних файлах, але командний рядок будується додаванням кожного вибраного імені файлу в кінці; загальна кількість викликів команди буде значно меншою, ніж кількість відповідних файлів. Командний рядок побудований приблизно так само, як xargsбудує його командні рядки. Лише один екземпляр {}дозволений в межах команди. Команда виконується в початковому каталозі. Якщо findвиникає помилка, це іноді може спричинити негайний вихід, тому деякі команди, що очікують на розгляд, можуть не запускатися. Цей варіант -execзавжди повертає істину.

-execdir командування ;

-execdir командування {} +

Можливо -exec, але вказана команда запускається з підкаталогу, що містить відповідний файл, який зазвичай не є каталогом, в якому ви почали знаходити. Це набагато більш безпечний метод для виклику команд, оскільки він дозволяє уникнути перегонів під час вирішення шляхів до відповідних файлів. Як і у випадку -exec дії, + форма -execdir буде будувати командний рядок для обробки більш ніж одного відповідного файлу, але будь-яке дане виклик команди буде перелічувати лише ті файли, які існують в одному підкаталозі. Якщо ви використовуєте цю опцію, ви повинні переконатися, що ваша $PATHзмінна середовище не посилається.; в іншому випадку зловмисник може виконувати будь-які команди, які їм подобаються, залишаючи файл із відповідним іменем у каталозі, в якому ви будете запускатись -execdir. Це ж стосується записів, у $PATHяких порожні або які не є абсолютними іменами каталогів. Якщо findвиникає помилка, це іноді може спричинити негайний вихід, тому деякі команди, що очікують на розгляд, можуть не запускатися. Результат дії залежить від того, використовується +або ;варіант; -execdir команда {} + завжди повертає true, тоді як -execdir команда {} ; повертає true, лише якщо команда повертає 0.

man xargs

-I замінити-вул

Замініть випадки заміщення str у початкових аргументах іменами, прочитаними зі стандартного вводу. Також пропуски без котирування не закінчують елементи введення; натомість роздільник - це символ нового рядка. Наслідки -xі -L 1.

-i[ заміна-str ], --replace[ =zamena-str ]

Цей параметр є синонімом для -Isubstitu-str, якщо вказано substitu-str . Якщо аргумент заміни str не вистачає, ефект такий же, як -I{}. Ця опція застаріла; використовувати -Iзамість цього.

Редагувати: і ось Чому БАШ ігнорує ці фігурні дужки:

man bash

{ список; }

список просто виконується в поточному середовищі оболонки. список повинен бути завершений новим рядком або крапкою з комою. Це відомо як команда групи. Статус повернення - це статус виходу зі списку. Зауважте, що на відміну від метахарактерів ( і ) , { і } є зарезервованими словами і повинні виникати там, де дозволено розпізнавати зарезервоване слово. Оскільки вони не викликають розрив слова, їх потрібно відокремити від списку пробілом або іншим метахарактером оболонки.

Наголос: список потрібно закінчувати новим рядком або крапкою з комою .


1
Дякую! Мені прикро, що той, хто писав man xargs, навіть не намагався пояснити, що {}насправді означає, а також автор не перенаправляв читача на пояснення -execна сторінці людини find.
Niko Gambt

@NikoGambt - Співчуваю ...
Дзинь

5
@NikoGambt Ну, {} насправді нічого не означає для xargs, за винятком того, що значення за замовчуванням для -i, яке застаріло. Я не впевнений, яке пояснення потрібно поза цим. У прикладі, який ви опублікували, це також могло бути xargs -Iab echo ab; це суто довільний вибір.
Випадково832

@ Random832 Після ще кількох тестувань -I, я тепер розумію, що насправді робить цей варіант. Так, {}довільно, як ви сказали. Мене просто розгубило пояснення If the replace-str argument is missing, the effect is the same as -I{}. Якби -Iбез аргументу були такі самі, як -I{}, тоді вони cat foo | xargs -I echo {}мали б такий же результат, що і біг cat foo | xargs -I{} echo {}. Однак вони не однакові. Перший - це помилка, і що ще більше мене бентежило повідомлення про помилку xargs: {}: No such file or directory, але це лише завдяки реалізації.
Ніко Гамбт

1
@NikoGambt -I(верхній регістр I) не може бути запущений без аргументу. Аргументом до -Iбуло echo. Це головна різниця між -Iі -i(а причина -i застаріла, оскільки варіанти з необов’язковими аргументами є рідкісними і заплутаними)
Random832
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.