xargs не распознает псевдонимы bash

Я пытаюсь запустить следующую команду:

find . -iname '.#*' -print0 | xargs -0 -L 1 foobar

где «foobar» — это псевдоним или функция, определенная в моем файле .bashrc (в моем случае это функция, принимающая один параметр). По-видимому, xargs не распознает их как то, что он может запустить. Есть ли умный способ исправить это?


person Ian Greenleaf Young    schedule 04.02.2009    source источник
comment
Это одна из причин, по которой я создаю сценарии в своей папке ~/bin вместо создания псевдонимов bash. Таким образом, я могу использовать свои псевдонимы из любой оболочки: BASH, ZSH, IPYTHON или FISH.   -  person Yoo    schedule 13.09.2009
comment
Вот похожий (хотя и не идентичный) вопрос: stackoverflow.com/questions/979453/   -  person Nathan Fellman    schedule 08.03.2010


Ответы (6)


Поскольку только ваша интерактивная оболочка знает об псевдонимах, почему бы просто не запустить псевдоним без разветвления через xargs?

find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done

Если вы уверены, что в ваших именах файлов нет символов новой строки (хм, зачем им это?), вы можете упростить это до

find . -iname '.#*' -print | while read -r i; do foobar "$i"; done

или даже просто find -iname '.#*' | ..., поскольку каталог по умолчанию — ., а действие по умолчанию — -print.

Еще одна альтернатива:

 IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done

сообщая Bash, что слова разбиваются только на символы новой строки (по умолчанию: IFS=$' \t\n'). Вы должны быть осторожны с этим, однако; некоторые скрипты плохо справляются с измененным $IFS.

person ephemient    schedule 04.02.2009
comment
Этот ответ отвечает, ПОЧЕМУ мы не можем использовать xargs и КАК мы можем использовать xargs с псевдонимом. - person Ivailo Bardarov; 24.11.2011
comment
Этот ответ дает нам альтернативы использованию xargs. Ответ, который работает с использованием xargs, см. в ответе @camh на соответствующий вопрос: stackoverflow.com/questions/979453/ (на который Натан Феллман ссылался выше) - person Noach Magedman; 16.01.2013

Используя Bash, вы также можете указать количество аргументов, передаваемых вашему псевдониму (или функции), например:

alias myFuncOrAlias='echo'  # alias defined in your ~/.bashrc, ~/.profile, ...
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0
echo arg1 arg2 | xargs  bash -cil 'myFuncOrAlias "$@"' arg0
person tilo    schedule 19.07.2010

Добавление пробела в конце команды с псевдонимом приводит к расширению других команд с псевдонимом:

alias xargs='xargs ' # aliased commands passed to xargs will be expanded

См. этот ответ для получения дополнительной информации:
https://stackoverflow.com/a/59842439/11873710

person ken hicks    schedule 21.01.2020

Это не работает, потому что xargs ожидает, что сможет exec использовать программу, заданную в качестве ее параметра.

Поскольку foobar в вашем случае - это просто псевдоним или функция bash, нет никакой программы для выполнения.

Хотя это включает в себя запуск bash для каждого файла, возвращаемого find, вы можете написать небольшой сценарий оболочки следующим образом:

#!/bin/bash
. $(HOME)/.bashrc
func $*

а затем передайте имя этого скрипта в качестве параметра xargs

person Alnitak    schedule 04.02.2009
comment
Где разместить этот скрипт, чтобы его распознал xargs? - person Nick Volynkin; 31.07.2015
comment
@NickVolynkin, куда хотите, если он находится либо в $PATH, либо сообщает его местоположение непосредственно xargs. - person Alnitak; 31.07.2015

Обычно я использую find следующим образом:

find . -iname '' -exec cmd '{}' \;

'{}' будет заменено именем файла, а \; необходимо, чтобы завершить цепочку выполнения. Однако, если это не работает с вашей функцией, вам может потребоваться запустить ее через bash:

find .. |sed -e "s/.*/cmd '&'/"|bash

Find печатает каждый файл в строке, sed просто добавляет к нему префикс вашей команды, а затем передает его в bash для выполнения. Сначала пропустите |bash, чтобы увидеть, что произойдет.

person Staale    schedule 04.02.2009
comment
Если вы используете новый поиск GNU, используйте вместо этого -exec cmd '{}' +: это больше похоже на xargs в том, что он объединяет аргументы в один запуск вместо выполнения новой команды cmd для каждого найденного файла. - person ephemient; 05.02.2009
comment
Я скорее думаю, что если бы его функция могла принимать несколько параметров, он бы не предоставлял параметры -L 1 для xargs... - person Alnitak; 05.02.2009
comment
О, вот что делает -L? Я не искал его, и я использую -n для этой цели. - person ephemient; 05.02.2009
comment
К сожалению, эти методы по-прежнему не работают с псевдонимами и функциями. Вероятно, потому что .bashrc вызывается только для интерактивных оболочек. Но первый - ловкий трюк. - person Ian Greenleaf Young; 07.02.2009

пытаться

find . -iname '.#*' -print0 | xargs -0 -L 1 $(foobar)
person Jacob Adamczyk    schedule 23.10.2018