Как использовать функцию bash, определенную в вашем .bashrc, с помощью find -exec

my.bashrc имеет следующую функцию

function myfile {
 file $1
}
export -f myfile

он отлично работает, когда я вызываю его напрямую

[email protected]:~$ myfile out.ogv 
out.ogv: Ogg data, Skeleton v3.0

он не работает, когда я пытаюсь вызвать его через exec

[email protected]:~$ find ./ -name *.ogv -exec myfile {} \;
find: `myfile': No such file or directory

Есть ли способ вызвать bash script функции с exec?

Любая помощь приветствуется.

Обновление:

Спасибо за ответ Джим.

Но это именно то, чего я хотел избежать в первую очередь, так как у меня есть много функций полезности, определенных в моих сценариях bash, я хотел использовать их с другими полезными командами, такими как find -exec.

Я полностью понимаю вашу точку зрения, но find может запускать исполняемые файлы, он не знает, что переданный аргумент является функцией, определенной в script.

Я получаю ту же ошибку, когда пытаюсь выполнить exec, находится в приглашении bash.

$ exec myfile out.ogv

Я надеялся, что может быть какой-то опрятный трюк, которому exec может дать некоторую гипотетическую команду вроде "bash -myscriptname -myfunctionname".

Думаю, я должен попытаться найти способ bash script как можно быстрее и запустить его с помощью exec.

Ответы

Ответ 1

Вы можете получить bash для запуска функции, поместив команду в bash StdIn:

bash$ find ./ -name *.ogv -exec echo myfile {} \; | bash

Вышеприведенная команда будет работать для вашего примера , но вам нужно обратить внимание на то, что все команды "myfile..." генерируются сразу и отправляются в один процесс bash.

Ответ 2

find ./ -name *.ogv -exec bash -c 'myfile {}' \;

Ответ 3

Мне удалось запустить его, возможно, более элегантно, как:

function myfile { ... }
export -f myfile
find -name out.ogv -exec bash -c '"[email protected]"' myfile myfile '{}' \;

Обратите внимание, что myfile задается дважды. Первый - параметр $0 script (и в этом случае он может быть в основном любым). Второй - имя запускаемой функции.

Ответ 4

$ cat functions.bash
#!/bin/bash

function myecho { echo "[email protected]"; }
function myfile { file "[email protected]"; }
function mycat { cat "[email protected]"; }

myname=`basename $0`
eval ${myname} "[email protected]"
$ ln functions.bash mycat
$ ./mycat /etc/motd
Linux tallguy 2.6.32-22-core2 ...
$ ln functions.bash myfile
$ myfile myfile
myfile: Bourne-Again shell script text executable
$ ln functions.bash myecho
$ myecho does this do what you want\?
does this do what you want?
$ 

где, конечно, функции могут быть более сложными, чем мои примеры.

Ответ 5

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

Ответ 6

даже simpiler

function myfile { echo $* ; }
export -f myfile

find . -type f -exec bash -c 'myfile "{}"'  \;

Ответ 7

Сценарии дочерней оболочки, похоже, поддерживают родительские функции, поэтому вы можете сделать script аналогичный этому:

'runit.sh'

#! /bin/bash

"[email protected]"

то do find -name out.ogv -exec ./runit.sh myfile '{}' \; и это работает!:)

Ответ 8

Спасибо Жоао. Это похоже на очень умное и элегантное решение. Незначительная проблема заключалась в том, что сначала мне нужно было запустить script для запуска функции myfile, например. Я позаимствовал из вашего предложения и сделал свой runint.sh следующим образом

#!/bin/bash
script_name=$1
func_name=$2
func_arg=$3
source $script_name
$func_name $func_arg

Теперь я могу запустить его следующим образом

$ find ./ -name *.ogv -exec ./runit.sh ~/.bashrc myfile {} \;
./out.ogv: Ogg data, Skeleton v3.0

В противном случае я получал

$ find ./ -name *.ogv -exec ./runit.sh myfile {} \;
./runit.sh: 1: myfile: not found

В любом случае спасибо большое.