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


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

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

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

4 54

4 ответа:

поскольку только ваша интерактивная оболочка знает об псевдонимах, почему бы просто не запустить псевдоним, не разветвляясь через 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

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

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

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

это не работает, потому что xargs планирует exec the программа задано в качестве параметра.

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

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

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

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

Я обычно использую найти так:

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

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

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

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