Чтобы лучше понять xargs

Я хочу понять использование xargs man в коде Ramion:

screen -t man /bin/sh -c 'xargs man || read'

Спасибо Рэмпиону: нам не нужен кот!

Зачем нам нужен xargs в команде?

Я понимаю xargs -часть следующим образом

  1. кот ничего для xargs
  2. xargs составляет список man-команд

У меня была идея, что xargs составляет список команд. Например,

find . -type f -print0 | xargs -0 grep masi 

то же самое, что и список команд:

find fileA AND grep masi in it 
find fileB AND grep masi in it 
           and so on for fileC, fileD, ...

person Léo Léopold Hertz 준영    schedule 13.07.2009    source источник
comment
Я открыл новую ветку о практической пользе рекурсивного grep в xargs по адресу stackoverflow.com/questions/1121807/   -  person Léo Léopold Hertz 준영    schedule 14.07.2009


Ответы (3)


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

xargs man ожидает ввода данных пользователем. Что необходимо. Поскольку в сценарии, из которого вы это взяли, я не могу вставить аргумент для человека, пока не создам окно. Таким образом, команда, которая запускается в окне, должна дождаться, пока я ей что-то дам, прежде чем она попытается запустить man.

Если бы мы просто запускали screen /bin/sh -d 'man || read', он всегда жаловался бы: «Какую справочную страницу вы хотите?» так как мы никогда не говорили об этом.

person rampion    schedule 13.07.2009

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

поэтому cat ждет, что что-то будет напечатано, а затем xargs запускает man с этим вводом.

xargs полезен, если вам нужно обработать много файлов, я часто использую его с выводом из find. xargs вставит в командную строку столько аргументов, сколько сможет.
Это отлично подходит для выполнения чего-то вроде

find . -name '*.o' -print | xargs rm
person Charlie    schedule 13.07.2009

Команда cat ни с чем не работает; он работает со стандартным вводом до тех пор, пока не будет сообщено, что ввод завершен. Как отмечает Рэмпион, команда cat здесь не нужна, но она работает со своим неявным вводом (стандартным вводом), а не ни с чем.

Команда xargs считывает вывод из cat и группирует информацию в аргументы команды man, указанной в качестве ее (единственного) аргумента. Когда он достигнет предела (настраивается в командной строке), он выполнит команду man.

Идиома find ... -print0 | xargs -0 ... имеет дело с именами файлов, которые содержат неудобные символы, такие как пробелы, символы табуляции и символы новой строки. Команда find печатает имя каждого файла, за которым следует ASCII NUL ('\0'); это один из двух символов, которые не могут встречаться в простом имени файла, а другой — '/' (который, конечно, появляется в путях, но не в простых именах файлов). Это не эквивалентно предоставленной вами последовательности; xargs группирует наборы имен файлов в один список аргументов до ограничения размера. Если имена достаточно короткие (обычно так и есть), то grep будет выполнено меньше, чем имен файлов.

Также обратите внимание, что grep печатает имя файла, в котором найден материал, только в том случае, если у него есть более одного файла для поиска, или если он поддерживает параметр, так что он всегда печатает имена файлов и используется параметр: '-H' это расширение GNU для grep, которое делает это. Портативный способ убедиться, что имена файлов всегда отображаются, состоит в том, чтобы указать /dev/null в качестве первого файла (то есть 'xargs grep something /dev/null'); поиск /dev/null не займет много времени.

person Jonathan Leffler    schedule 13.07.2009
comment
Спасибо за ваш ответ! Так что \0 and / не может быть в именах файлов. xargs имеет довольно непрактичный предел. Существуют варианты grep, такие как GNU grep. --- Вы имеете в виду, что xargs имеет /dev/null в качестве первого файла? Вы имеете в виду, что некоторые варианты xargs требуют /dev/null в качестве первого аргумента? - person Léo Léopold Hertz 준영; 14.07.2009
comment
Это вовсе не непрактичный предел, Маси. На самом деле, это в высшей степени практично. Что касается /dev/null, он имеет в виду указать это как жестко закодированный первый параметр имени файла для grep: xargs -0 grep masi /dev/null. После этого Xargs добавит дополнительные имена файлов. Поскольку grep было присвоено несколько имен, он будет печатать имена файлов всякий раз, когда находит совпадение, чего он не делает, когда его командная строка содержит только одно имя файла. Более прямым, чем трюк /dev/null, является использование опции -H команды grep. - person Rob Kennedy; 14.07.2009
comment
Я открыл новую ветку на основе комментария Роба по адресу stackoverflow.com /вопросы/1122218/ - person Léo Léopold Hertz 준영; 14.07.2009