Xargs не распознает псевдонимы bash
Я пытаюсь запустить следующую команду:
find . -iname '.#*' -print0 | xargs -0 -L 1 foobar
где "foobar" - это псевдоним или функция, определенные в моем файле .bashrc(в моем случае это функция, которая принимает один параметр). Очевидно, xargs не распознает их как вещи, которые он может запустить. Есть ли разумный способ исправить это?
Ответы
Ответ 1
Так как только ваша интерактивная оболочка знает об псевдонимах, почему бы просто не запустить псевдоним без прокрутки через xargs
?
find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done
Если вы уверены, что у ваших имен файлов нет новых строк (ick, зачем они?), вы можете упростить это для
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
.
Ответ 2
Используя 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 "[email protected]"' arg0
Ответ 3
Это не работает, потому что xargs
ожидает, что сможет exec
указать программу в качестве ее параметра.
Так как foobar
в вашем случае - это просто псевдоним или функция bash
, программа не должна выполняться.
Хотя он включает запуск bash
для каждого файла, возвращаемого find
, вы можете написать небольшую оболочку script, таким образом:
#!/bin/bash
. $(HOME)/.bashrc
func $*
а затем передать имя этого script в качестве параметра xargs
Ответ 4
Обычно я использую find следующим образом:
find . -iname '' -exec cmd '{}' \;
'{}' заменяется именем файла и \; необходимо для завершения цепочки выполнения. Однако, если это не работает с вашей функцией, вам может потребоваться запустить ее через bash:
find .. |sed -e "s/.*/cmd '&'/"|bash
Найти печатает каждый файл в строке, sed просто префикс этой команды, а затем передать его на bash для выполнения. Сначала пропустите | bash, чтобы увидеть, что произойдет.