Решения тех проблем, с которым мне приходилось сталкиваться.

среда, 20 октября 2010 г.

Длинная командная строка через xargs

Иногда приходится выполнить команду с таким количеством аргументов, что '*' (звездочка) уже не работает - shell пытается создать слишком длинную командную строку. Выход - разбить список на несколько более мелких и выполнить команду для каждого из них. В том числе и для этого создана команда xargs.
Она получает список из stdin и выполняет переданную ей команду подставляя список в качестве ее аргументов. Для разбития списка на куски есть разные опции (-n или -s).
Но до сего момента я не подозревал, что список аргументов может быть не в самом конце нужной команды, но и в любом месте.
Для примера. Если нужно скопировать кучу файлов и cp * <dest> не работает. Пробуем писать:

ls * | xargs -n 1000 cp /dest

И оно тоже не будет работать, потому как список аргументов от xargs будет подставлен в конец команды cp и в итоге будет выглядеть примерно как:

cp /dest arg1 arg2 ... argn

Как поместить список аргументов в нужное место? А вот это в man'е не совсем очевидно при первом прочтении. А в итоге нужно делать так:

ls * | xargs -n 1000 -I FILES cp FILES dest

Что тут происходит? Опция -I сообщает xargs, что если подстрока 'FILES' встретится где-либо в части исполняемой команды (initial arguments), то именно в это место и нужно раскрыть список аргументов из stdin.

Комментариев нет: