sharrajesh
sharrajesh

Reputation: 401

how to use a bash function defined in your .bashrc with find -exec

my .bashrc has the following function

function myfile {
 file $1
}
export -f myfile

it works fine when i call it directly

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

it does not work when i try to invoke it through exec

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

is there a way to call bash script functions with exec?

Any help is greatly appreciated.

Update:

Thanks for the response Jim.

But that's exactly what I wanted to avoid in the first place, since I have lot of utility functions defined in my bash scripts, I wanted to use them with other useful commands like find -exec.

I totally see your point though, find can run executables, it has no idea that the argument passed is function defined in a script.

I will get the same error when I try to exec is on bash prompt.

$ exec myfile out.ogv

I was hoping that there may be some neat trick that exec could be given some hypothetical command like "bash -myscriptname -myfunctionname".

I guess I should try to find some way to create a bash script on the fly and run it with exec.

Upvotes: 17

Views: 7689

Answers (9)

user23107660
user23107660

Reputation:

This oneliner should do in my case:

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

Upvotes: 0

kdubs
kdubs

Reputation: 1722

even simpiler

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

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

Upvotes: 3

Petr
Petr

Reputation: 63389

I managed to run it perhaps more elegantly as:

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

Notice that myfile is given twice. The first one is the $0 parameter of the script (and in this case it can be basically anything). The second one is the name of the function to run.

Upvotes: 7

Torsten Scheck
Torsten Scheck

Reputation: 614

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

Upvotes: 7

sharrajesh
sharrajesh

Reputation: 401

Thanks Joao. This looks like very clever and elegant solution. Little issue was that I had to source my script first to run myfile function e.g. I borrowed from your suggestion and made my runint.sh as follows

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

Now I can run it as follows

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

Otherwise I was getting

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

Anyway thanks a lot.

Upvotes: 1

too much php
too much php

Reputation: 91058

You can get bash to run a function by putting the command into bash's StdIn:

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

The command above will work for your example but you need to take note of the fact that all of the 'myfile...' commands are generated at once and sent to a single bash process.

Upvotes: 5

msw
msw

Reputation: 43527

$ 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?
$ 

where, of course, the functions can be a tad more complex than my examples.

Upvotes: 6

João Portela
João Portela

Reputation: 6456

Child shell scripts seems to keep the parent functions so you could do a script similar to this one:

'runit.sh'

#! /bin/bash

"$@"

then do find -name out.ogv -exec ./runit.sh myfile '{}' \; and it works! :)

Upvotes: 2

Jim Lewis
Jim Lewis

Reputation: 45115

I don't think find can do this, since it's the find command itself that's executing the command, and not the shell you're currently running...so bash functions or aliases won't work there. If you take your function definition and turn it into a separate bash script called myfile, make it executable, and install it on your path somewhere, find should do the right thing with it.

Upvotes: 3

Related Questions