Різниця між "xargs" та заміною команд?


14

У багатьох випадках я використовую замість команди замість xargs. Наприклад rm $(ls), те саме, щоls | xargs rm

У чому насправді відмінності між ними?

Я думаю, що одна з відмінностей полягає в тому, що підміна команд працює в нижній частині, а xargsпрацює в поточній оболонці, але я не впевнений.

Перерахуйте, будь ласка, відмінності.

Відповіді:


9

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

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

Третє питання полягає в тому, що глобуси розширені, тому якщо у файлі зірочки чи знаки запитань у своєму імені, несподівані результати будуть.

Ви можете знайти приємну дискусію з цього питання тут: http://mywiki.wooledge.org/ParsingLs

Правильний синтаксис був би

echo rm *

або якщо вам потрібно використовувати xargs,

find . -maxdepth 1 -print0 | xargs -0 echo rm

Видаліть, echoколи вихід виглядає правильним.


1
@Sinoosh: xargsтакож працює в нижній частині корпусу через трубу, якщо ви не включите shopt -s lastpipe, і в цьому випадку вона буде працювати в поточній оболонці. Я не вважаю, що запуск в підпакеті не є проблемою, хоча в цьому випадку ви не змінюєте жодних змінних.
user000001

1
@Sinoosh: Щоб передавати аргументи один за одним, ви можете використовувати -lпрапор, наприклад find . -maxdepth 1 -print0 | xargs -0 -l rm. Для другого питання ви не можете скористатись lsтим, xargs -0що ls не
ділить

1
@Sinoosh: Не перший абзац, а другий: xargs без -0параметра страждає від проблеми пробілів.
user000001

1
Читайте man xargs, використовуйте echoдля тестування, ні rm. xargsдозволяє нам перевищувати межі оболонки (деякий буфер обмежений 65K, список імен не є).
waltinator

1
@Sinoosh: Я не маю корисних посилань, але ви можете набрати, xargs --show-limitsі ви побачите обмеження, встановлене у вашій системі,
user000001
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.