Трубопровод для «ввода» команды

10

Я хочу узнать тип нескольких команд. Возможно ли передать по конвейеру или xargsрезультат поиска findв typeкоманду в Linux?

Например:

find . -name anacron | type

или

find . -name anacron | xargs type
LjinKazama
источник
Я думаю, что ответ Оли - лучший ответ. Хаос ответ просто работает, но Оли ответ умный.
Гелио

Ответы:

17

typeэто не нормальная команда. Это скорлупа бутина. Увидеть:

$ type type
type is a shell builtin

Итак, вам нужно обратиться bashс помощью, -cчтобы достичь того, что вы хотите

$ find . -name anacron | xargs -I '{}'  bash -c "type {}"

Или даже проще (не нужно xargs):

$ find . -name anacron -exec bash -c "type {}"  \;

Он будет вызывать bash -c "type ./file"каждый найденный файл find. -Iв xargsсмысле, мы определяем здесь заполнитель {}для использования позже. Этот заполнитель заменяется найденным именем файла.

Почему встроенные оболочки не работают с xargs:

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


xargs читает элементы из стандартного ввода [...] и выполняет команду

Команда в этом случае является простой исполняемой, а встроенная оболочка не является исполняемым файлом. Его нельзя найти в файловой системе. Это внутри самой оболочки. Таким образом, вы должны вызвать оболочку и сказать вызываемой оболочке вызвать встроенную команду. Вот что случилось с bash -c "command".

хаос
источник
3
Вы можете сжать это доfind ... -exec bash -c 'type "$@"' _ {} +
Муру
2
@Muru, действительно, я прочитал свой собственный ответ снова и увидел его =)
хаос
11

Здесь есть несколько проблем (некоторые уже выделены):

  • typeявляется встроенным Это не команда, которая решена, это функция внутри bash. См man bash-builtins. Он работает только в контексте bash, поэтому не является раздвоенным xargsили -execраздвоенным.
  • typeиспользуется для поиска собственного пути. Если вы дадите ему путь (как findобычно), он, вероятно, просто вернет этот путь. readlink -fможет быть лучше, если вы просто пытаетесь разрешить символические ссылки; и вы можете трубить xargs readlinkили -exec readlink -f {} +целый день.

Это не значит, что вы не можете делать то, что пытаетесь. Есть два варианта. Команда typeможет обрабатывать много имен одновременно, так что вы можете просто указать все имена сразу:

type $(find /usr/sbin -name anacron)

Для многих команд, если слишком много аргументов, вы превысите ограничение длины командной строки (см. getconf ARG_MAX). Однако это не будет применяться в этом случае, поскольку typeвстроено в оболочку и не генерирует новый идентификатор процесса (ограничение длины применяется к функции exec (), используемой дочерним процессом в обычной командной строке).

Оли
источник
1
Спасибо Оли! Этот новичок в Linux узнал что-то новое о «типе» и его поведении.
LjinKazama