Как использовать функцию Bash, определенную в вашем .bashrc с find -exec - PullRequest
17 голосов
/ 17 июня 2010

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

function myfile {
 file $1
}
export -f myfile

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

rajesh@rajesh-desktop:~$ myfile out.ogv 
out.ogv: Ogg data, Skeleton v3.0

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

rajesh@rajesh-desktop:~$ find ./ -name *.ogv -exec myfile {} \;
find: `myfile': No such file or directory

есть ли способ вызвать функции bash-скрипта с помощью exec?

Любая помощь с благодарностью.

Обновление:

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

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

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

Я получу ту же ошибку при попытке выполнить exec в приглашении bash.

$ exec myfile out.ogv

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

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

Ответы [ 8 ]

7 голосов
/ 14 апреля 2011
find ./ -name *.ogv -exec bash -c 'myfile {}' \;
7 голосов
/ 14 апреля 2012

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

function myfile { ... }
export -f myfile
find -name out.ogv -exec bash -c '"$@"' myfile myfile '{}' \;

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

6 голосов
/ 17 июня 2010
$ cat functions.bash
#!/bin/bash

function myecho { echo "$@"; }
function myfile { file "$@"; }
function mycat { cat "$@"; }

myname=`basename $0`
eval ${myname} "$@"
$ 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 голосов
/ 17 июня 2010

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

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

Приведенная выше команда будет работать для вашего примера , но вам необходимо принять во внимание тот факт, что все команды 'myfile...' генерируются одновременно и отправляются в один процесс bash.

3 голосов
/ 23 марта 2013

даже проще

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

find . -type f -exec bash -c 'myfile "{}"'  \;
3 голосов
/ 17 июня 2010

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

2 голосов
/ 17 июня 2010

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

'runit.sh'

#! /bin/bash

"$@"

, затем выполните find -name out.ogv -exec ./runit.sh myfile '{}' \;, и этоработает!:)

1 голос
/ 17 июня 2010

Спасибо, Жуан. Это выглядит как очень умное и элегантное решение. Небольшая проблема заключалась в том, что мне сначала нужно было написать свой сценарий для запуска функции 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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...