Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 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, чтобы увидеть, что произойдет.