LINUX.ORG.RU

Мне показалось, или на лоре есть пользователь Xintrea и он автор?

 


2

2

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

https://webhamster.ru/mytetrashare/index/mtb0/1500377408wvogu8h41a

★★★★★

Последнее исправление: AVL2 (всего исправлений: 1)

В сети есть попытка разобраться с командой xargs.

Чего только люди не делают, лишь бы man xargs не читать.

dexpl ★★★★★
()
Ответ на: комментарий от dexpl

Бывают маны такой длины, что нагуглить получается в разы быстрей, чем по манам искать.

А в некоторых манах (превед, ImageMagick) вообще нихрена не пишут!

anonymous
()

В статье есть ряд досадных упущений

Как ты политкорректно назвал смесь из криво пересказанного мана и полной ахинеи.

redgremlin ★★★★★
()
Ответ на: комментарий от AVL2

Как-то он очень странно пытался разобраться. Хренова куча букв, а так и не узнал ни про опцию -d, ни про -I, ни про -L
А перлы вида :


Как это работает объяснить сложно. Ведь опцию "-0" имеет команда xargs, а не команда rm. В man-странице команды rm нет никаких указаний на то, что в случае разделения имен файлов нулевыми символами пробельные символы в именах файлов будут обрабатываться как литералы, а не как разделители. Для автора статьи такое поведение остается загадкой, и пока не нашлось специалиста, который бы объяснил, что же на самом деле происходит.


вообще подрывают веру в человечество.

redgremlin ★★★★★
()
Ответ на: комментарий от redgremlin

Да понятно все это, но справедливости ради, багов там тоже ведь хватает.

вот сейчас мучаю команду find в связке с xargs и понять не могу, почему ж она внезапно ломается? Я ими 10 лет оперирую а в упор не понимаю, что ему не нравится? Почему с простым условием и -print0 все работает, со сложным условием и без -print0 тоже, но со сложным и -print0 все умирает?!!!

echo 1 good
find $TOP  -not  -group "$GROUP" -or -not -user "$USER"
echo 2 bad
find $TOP  -not  -group "$GROUP" -or -not -user "$USER" -print0 | xargs -0 echo
echo 3 good
find $TOP  -not  -group "$GROUP"  -print0 | xargs -0  echo


1 good
/mnt/share/other/workgroups/test
/mnt/share/other/workgroups/test/New Text Document - Copy.txt
/mnt/share/other/workgroups/test/New Text Document.txt
/mnt/share/other/workgroups/test/New folder
2 bad

3 good
/mnt/share/other/workgroups/test /mnt/share/other/workgroups/test/New Text Document - Copy.txt /mnt/share/other/workgroups/test/New Text Document.txt /mnt/share/other/workgroups/test/New folder
AVL2 ★★★★★
() автор топика
Последнее исправление: AVL2 (всего исправлений: 2)
Ответ на: комментарий от AVL2

нашел. -print0 должно быть перед всеми аргументами.

find $TOP -print0  -not  -group "$GROUP" -or -not -user "$USER"  | xargs -0

работает как надо

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от AVL2

Вот видишь, xargs тут и вообще не причём. А ты попался, потому что тоже не очень внимательно читал документацию. -print0 — это такое же выражение, как и другие, включая тесты, просто возвращает всегда true. А два выражения подряд неявно связываются через and, причём, если первое возвращает false, второе не выполняется. Т.е. реально твоя команда выглядела

find $TOP -not  -group "$GROUP" -or -not -user "$USER" -and -print0

А приоритет у and выше or.

redgremlin ★★★★★
()
Ответ на: комментарий от AVL2

потому что

find $TOP \( -not  -group "$GROUP" -or -not -user "$USER" \) -print0 | xargs -0 echo

deadNightTiger ★★★★★
()
Ответ на: комментарий от redgremlin

не должен, должен напечатать все файлы

Ой ли?
true and false = false
true and true = true
print0 and expr = expr

Вот только выражение в скобках должно быть, иначе \( -print0 -and -not ... \) -or -not ...

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 2)
Ответ на: комментарий от AVL2

Проблематику процесса ты в мане не узнаешь.

Ровно наоборот — человек, пишущий, что "в Linux существует очень странная команда xargs, которую весьма любят гуру, но не спешат объяснять как она работает. Интернет завален рецептами «как пользоваться xargs», но ни в одном из них внятно не написано самого главного: что эта команда вообще делает", явно никогда не открывал man xargs. Специально для подобных автору людей процитирую первый абзац оттуда:

This manual page documents the GNU version of xargs. xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or newlines, and executes the command (default is /bin/echo) one or more times with any initial-arguments followed by items read from standard input. Blank lines on the standard input are ignored.

dexpl ★★★★★
()
Ответ на: комментарий от dexpl

Ты будешь смеяться, но он процитировал этот отрывок. Но, очевидно, не понял написанного.

redgremlin ★★★★★
()
Ответ на: комментарий от dexpl

Ну и где здесь проблематика? Это просто прямое очень краткое описание, что конкретно утилита делает и никакого намека на то, зачем она вообще была написана.

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от redgremlin

Да, надо проверять и подозреваю, что да, работает неверно.

И не совсем понятно, как исправить. Уж больно скобки не хочется ставить.

Что реально плохо, простой print у него забит по умолчанию и работает как надо. Так почему было не сделать было опцию, чтобы она меняла поведение неявно указанного принята, а не была отдельным оператором?

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от AVL2

Знаешь, мне до сих пор казалось, что ответ на вопрос «что конкретно утилита делает» является ответом и на вопрос «зачем она вообще была написана» — затем, чтобы делать то, что она делает, нет?

dexpl ★★★★★
()
Ответ на: комментарий от dexpl

ответ на вопрос «что конкретно утилита делает» является ответом и на вопрос «зачем она вообще была написана»

Вообще говоря, далеко не всегда.

Ну и есть ещё важный вопрос «как этим правильно пользоваться?». Его в манах освещают достаточно редко.

Но это не отменяет необходимость внимательно читать (и пытаться понять, конечно) маны, если есть желание действительно разобраться, как оно работает.

anonymous
()
Ответ на: комментарий от AVL2

Уж больно скобки не хочется ставить.

Это почему? Скобки ставить придётся, как ещё ты собираешься передать сложное условие поиска find'у? Скобки — твои друзья.

Что реально плохо, простой print у него забит по умолчанию и работает как надо. Так почему было не сделать было опцию, чтобы она меняла поведение неявно указанного принята, а не была отдельным оператором?

Не распарсил... Почему плохо? Какую опцию?

В POSIX'е написано, что:

if the given expression does not contain any of the primaries -exec, -ok, or -print, the given expression shall be effectively replaced by:

( given_expression ) -print

А если уж ты ставишь явный -print, то и скобки явные надо указывать, по необходимости.

мучаю команду find в связке с xargs и понять не могу, почему ж она внезапно ломается? Я ими 10 лет оперирую а в упор не понимаю

За десять лет-то можно было и маны внимательно почитать. Даже несколько раз.

anonymous
()

100 долл. паспортные данные, более подробная информация по договорной цене.

anonymous
()
Ответ на: комментарий от anonymous

Это почему? Скобки ставить придётся, как ещё ты собираешься передать сложное условие поиска find'у? Скобки — твои друзья.

потому, что башу они тоже нравятся. и их приходится эскейпить, а когда передаешь через ssh или в другой баш, то эскейпить и сам слеш, что выливается в три слеша перед кажой скобкой.

А если уж ты ставишь явный -print, то и скобки явные надо указывать, по необходимости.

ну вот это и раздражает, что для неявного print скобки они ставят, а для точно такого же print. только с разделителем нулем уже опачки, скобок нет. Мне ведь и принт никакой не нужен, я просто хочу, чтобы пробелы внутри аргументов сохранили, это в чистом виде опция, а не команда.

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от redgremlin

Кроме возвращения true print ещё имя файла печатает.

Угу, что-то отвлекся. Кстати, в связи с отрицательными условиями есть повод использовать старый трюк -prune -o -print:

find $TOP \( -group "$GROUP" -o -user "$USER" \) -prune -o -print0 | xargs -0 -n1 echo
find $TOP \( -group "$GROUP" -o -user "$USER" \) -prune -o -print
Для попавших под условие сработает -prune, для остальных -print0.

Если правильно помню...

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 2)
Ответ на: комментарий от bormant

Кстати, я так до конца и не понял, что делает -prune и почему оно везде идет в связке с -o ?

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от AVL2

Кстати, я так до конца и не понял, что делает -prune и почему оно везде идет в связке с -o ?

Ты еще не боишься по-честнаку рассказывать что ты чего-то не понимаешь? Да еще и на лоре, где все всё знают, читают маны между строк и связываются с мозгами авторов утилит через астрал? Нет? А если на тебя еще дермища выльют всёпонимальщики и обсудят твой интеллект и генетику, вместо того чтоб обсуждать тему топика? Тоже нет? Хорошо, тогда продолжим.

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

Xintrea ★★★★★
()
Ответ на: комментарий от Svobodniy

Потому, что два ЛОРовца нашли друг друга в интернете. Это как два китайца видели друг друга в Зимбабве и по приезду нужно обязательно это обсудить.

Ramil ★★★★
()
Последнее исправление: Ramil (всего исправлений: 1)
Ответ на: комментарий от Xintrea

Нет, не боюсь. Твои знания и опыт, это твой базис, твой капитал, который работает и всегда будет работать на на тебя, поэтому начиная с определенного уровня уже нет нужды постоянно искать одобрения окружающих. Более того, все чаще возникает соблазн наоборот лишний раз поскромничать.

Но я тебя понимаю. Я ведь тоже уходил с лора. Я уже даже не помню на кого и по какому поводу я там так обиделся, что поменял и выкинул пароль своего профиля AVL. Но время идет, ЛОР живет и пользы от него все равно гораздо больше, чем всего остального. Даже в этом треде есть много полезного, ведь я и правда не задумывался о том, как именно find интерпретирует действия, даже в голову не приходило, что это тоже условие. Теперь все стало на свои места.

Советы мне есть куда кидать, https://bitbucket.org/avlubimov/comp-house.repo/wiki/Home будет время, накидаю и про xargs

Но без обид, с xargs ты не разобрался чуть более чем совсем из за чего твоя статья сильно запутывает. Для понимания, попробуй разобраться, почему xargs так хочет все упаковать в один вызов и если это так уж хорошо, то почему он иногда автоматически делит этот один вызов на несколько? Почему просто не сделать это средствами баша или любого шаблонизатора?

Чем конструкция

ls `find -type f /tmp`

или 

for ITEM in `find -type f /tmp`; do ls "$ITEM"; done

хуже чем


find -type f /tmp  |  xargs ls

К чему было городить весь этот огород?

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от redgremlin

Как-то он очень странно пытался разобраться. Хренова куча букв, а так и не узнал ни про опцию -d, ни про -I, ни про -L

вообще подрывают веру в человечество.

Софт давно стал артефактом, по исследованию свойств и возможностей которого написано кучу научных трудов и опции -o, -d и прочие ещё не известные ждут тех, кто сможет их исследовать и совершить открытие.

torvn77 ★★★★★
()

Кстати, еще пара загадок для мудрых баш-извр... программистов.

Можно ли с xargs провернуть два фокуса:

1) промониторить его работу, заставив перед каждым вызовом команды или после него, например что то выводить, точку например. Самый очевидный вариант, вызывать в xargs скрипт, а в этом скрипте уже прописывать все нужные действия, но есть опасения, что будут проблемы с пробелами и прочими вещами да и неспортивно.

2) вызвать xargs с командой с конвейером, например

find /tmp/tmp | xargs cat /tmp/facl-rules | setfacl --from-file=-

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от AVL2

хуже чем

«чем» невалидный — сперва путь, потом выражение:

find /tmp -type f

bormant ★★★★★
()
Ответ на: комментарий от AVL2

1. xargs -t ?
2. Из твоей команды не очень понятно, что тебе надо, но конвеер делается как-то так:

echo "a" | xargs -I text sh -c 'echo text| tr a A'
A

redgremlin ★★★★★
()
Ответ на: комментарий от AVL2

Понятно что отдельные потоки порождаются вместо того чтоб передать просто длинную строку с разделителями и прожевать ее в одном потоке.

Но кого это волнует с начала века?

И главное: чтобы это дело работало, вызываемая программа должна уметь так работать. Не xargs должна уметь, а вызываемая. И без этого магии не получится. Об этом в 90 перцентах статей вообще не говорится. И здесь еще никто об этом не сказал. И даже ты вместо того чтоб изложить эту мысль, пишешь «догадайся». Я не в обиду, а просто к тому, что если неподготовленный чел начнет читать это обсуждение, то в таком изложении ничего нового не узнает.

Xintrea ★★★★★
()
Ответ на: комментарий от redgremlin

Давай, верни веру в человечество, и объясни сие загадочное поведение. Только без «догадайся», «очевидно», «где-то там написано» и прочей шелухи. Я внимаю.

Еще объясни как так две команды, которые посимвольно идентичны, возвращают разный результат. В статье этот пример есть.

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

и объясни сие загадочное поведение

Загадочно оно только для тех, кто ман не читал. А там ясно написано, что по умолчанию разделителем объектов являются пробельные символы и перевод строки. Т.е. две строки

./file
./new file

образуют три объекта: './file', './new', 'file' и команда (в твоём случае rm) получает _три_ аргумента. В случае же find … -print0 на вход идёт одна строка
./file\x00./new file\x00

которую xargs -0 делит по \x00, игнорируя пробельные символы, и образуются два объекта: './file', './new file' и команда получает _два_ аргумента

Еще объясни как так две команды, которые посимвольно идентичны, возвращают разный результат

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

redgremlin ★★★★★
()
Ответ на: комментарий от Xintrea

Но кого это волнует с начала века?

Во первых, find писалась не в этом веке. Тогда разница в быстродействии составляла сотни раз. Но и теперь это разы если не десятки раз.

Во вторых, в этом веке, у меня есть, например, небольшой архив, 900 000 файлов. Как думаешь, насколько это актуально при их обработке?

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

Представь себе, что у тебя тысяча элементов. Ты запускаешь команду в цикле. И видишь, что что-то идет не так. Что будет если ты нажмешь на ctrl-c, чтобы прервать ее? А что будет, если команда открывает графическое окно, например, ты составил поиском коллекцию и запустил проигрыватель или просмотрщик картинок?

Быстродействие, это хорошо, но тут не только и даже не столько оно имеет значение.

И главное: чтобы это дело работало, вызываемая программа должна уметь так работать. Не xargs должна уметь, а вызываемая.

Естественно и все программы, для которых это актуально, умеют работать со списком. Программу так и назвали eXtendedARGumentS потому что она конструирует аргументы командной строки, а не xfor, например, или xcycles, которые и так уже есть в баше.

И даже ты вместо того чтоб изложить эту мысль, пишешь «догадайся».

Не догадайся, а подумай. Твой мыслительный процесс принесет пользу всем и тебе в первую очередь. Потому что ты наверняка в процессе своих умозаключений нароешь то, что я не знал или не осознавал. А так, это будет простой пересказ моих (заблуждений) находок. И мне пользы никакой и тебе выслушать и забыть...

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от redgremlin

1) xargs -t кстати, почему бы и нет. Для отладки и простейшего профайлинга вполне пойдет.

2) Нет, задача стоит так, сделать переустановку facl с родительской директории вниз по дереву. Для этого есть setfacl и getfacl, которые здорово с этим справляются.

им вообще ничего кроме самих себя и не надо

topdir=/path/to/top
getfacl $topdir | setfacl --set-file=-  -R $topdir

Вот только на миллионе файлов это все умирает...

Поэтому хотелось бы получить больше контроля обрабатывая поток файлов порциями через xargs. но setfacl хотит список аклов получать или из файла или из станадртного потока ввода. Файл создавать не хочется, хоть это и выход, а пайп не проглатывает xargs.


ACL=`getfacl $topdir`
find $topdir -print0 | xargs -0  echo $ACL | setfacl  --set-file=- 

Но что то мне подсказывает, что наиболее прямое решение все таки создать временный файл с аклами и подставить его без всяких конвейеров...

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от redgremlin

Кстати, есть еще один костылик в xargs - -d

#исходные файлики с пробелами:

find /tmp -name "sk*"  2>/dev/null 
/tmp/skype-2680
/tmp/skypeforlinux Crashes

#просто так не работает:

find /tmp -name "sk*"  2>/dev/null | xargs  ls -ld
ls: невозможно получить доступ к /tmp/skypeforlinux: Нет такого файла или каталога
ls: невозможно получить доступ к Crashes: Нет такого файла или каталога
drwx------ 3 avl avl 4096 ноя 27 16:41 /tmp/skype-2680

#Устанавливаем разделитель строго на \n и теперь:

find /tmp -name "sk*"  2>/dev/null | xargs -d \\n ls -ld
drwx------ 3 avl avl 4096 ноя 27 16:41 /tmp/skype-2680
drwx------ 2 avl avl 4096 ноя 27 16:40 /tmp/skypeforlinux Crashes

#-print0 проще и удобней, но можно и так...
AVL2 ★★★★★
() автор топика
Последнее исправление: AVL2 (всего исправлений: 1)
Ответ на: комментарий от Xintrea

Не ссорьтесь, девочки. У вас ведь много общего — вы обе маны читать не любите.

anonymous
()
Ответ на: комментарий от torvn77

совершить открытие

Открыть, наконец, man find и man xargs?

anonymous
()
Ответ на: комментарий от AVL2

Почему костыль? Штатная возможность. Полезна, например, если строки состоят из полей, разделённых не пробельными символами, например в случае с файлом формата key=value это делается с -d = -L 1. Я это, к слову, и имел ввиду в начале этого треда — хотелки из статьи можно было реализовать и с -d, и с -L, и -I, не упираясь в -n 1, после решая проблемы, созданные самим собой самому себе.

redgremlin ★★★★★
()
Ответ на: комментарий от AVL2

Можно ли с xargs провернуть два фокуса

Можно.

1) ... вызывать в xargs скрипт, а в этом скрипте уже прописывать все нужные действия, но есть опасения, что будут проблемы с пробелами

Меньше, чем тебе кажется. Например:

find /usr/ports/dist -type f | xargs -n1 -Ixxxx sh -c 'case xxxx in (*.xz) xz -t xxxx;; (*.bz2) bzip2 -t xxxx;; (*.gz) gzip -t xxxx;; (*) echo xxxx;; esac'

2) вызвать xargs с командой с конвейером

Да хоть два xargs с конвейером. В моей history:

$ history 1 | grep 'xargs.*|.*xargs' | wc -l 
84
Пара примеров:
awk '{print $3}' < .footprint | xargs dirname | sort -u | tail -n+4 | xargs -n1 -Ixxxx pkginfo -o /xxxx
find -name '*.pkg.tar.xz*' -printf "%h\n" | xargs -n1 basename | xargs prt-get isinst | grep 'not installed'
А если ты имеешь в виду конвейер внутри команды, которую вызывает xargs, то см. п.1. А то, что ты написал, работать, очевидно, не будет.

anonymous
()

Кстати, судя по статье и комментариям здесь, у меня складывается впечатление, что большая часть непониманий относится не к xargs или find, а к тому, как шелл парсит команды.

Изучите, как работает шелл, господа. Очень многое сразу прояснится.

anonymous
()
Ответ на: комментарий от AVL2

Тебе же redgremlin уже написал, как делать конвейер внутри вызова xargs.

Для твоего конкретного случая будет примерно так:

find $topdir -print0 | xargs -0 -Ixxxx sh -c "echo $ACL | setfacl  --set-file=- xxxx"
Обрати внимание, чтобы твоя переменная $ACL раскрылась до подстановки в xargs, кавычки должны быть двойными. В случаях, если внешних переменных нет, лучше использовать одинарные, во избежание.

anonymous
()
Ответ на: комментарий от Ramil

Я знаю, я пароль выкинул. Да и не принципиально это.

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от redgremlin

Костыль в конкретном случае с возвратом строки, потому что эскейпить надо и чем больше ты его заворачиваешь, тем больше эскейпить.

С разделителями, которые не требуют эскейпов, вопросов нет, все разумно.

-n 1 действительно бессмысленное решение. В этом случае обычный for в баше порвет xargs по удобству и возможностям как тузик грелку.

AVL2 ★★★★★
() автор топика
Ответ на: комментарий от AVL2

что-то из этого наверняка в busybox работать не будет, могу ошибаться.

splinter ★★★★★
()
Ответ на: комментарий от Xintrea

Ты еще не боишься по-честнаку рассказывать что ты чего-то не понимаешь? Да еще и на лоре, где все всё знают, читают маны между строк и связываются с мозгами авторов утилит через астрал? Нет? А если на тебя еще дермища выльют всёпонимальщики и обсудят твой интеллект и генетику, вместо того чтоб обсуждать тему топика?

Сколько я раз говорил на ЛОРе, что чего-то не понимаю - дерьмом был полит только однажды, анонимусом, который, как выяснилось позже, сам опозорился со своим знанием предмета. Наверное, ты как-то не так говоришь.

hobbit ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.