我的.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
有没有办法用exec调用bash脚本函数?
非常感谢任何帮助。
感谢吉姆的回复。
但这正是我首先想要避免的,因为我在 bash 脚本中定义了很多实用函数,我想将它们与其他有用的命令(如 find -exec)一起使用。
我完全明白你的观点,find 可以运行可执行文件,它不知道传递的参数是脚本中定义的函数。
当我尝试在 bash 提示符下执行时,我会得到同样的错误。
$ exec myfile out.ogv
我希望可能有一些巧妙的技巧,可以给 exec 一些假设的命令,例如“bash -myscriptname -myfunctionname”。
我想我应该尝试找到一些方法来动态创建 bash 脚本并使用 exec 运行它。
find ./ -name *.ogv -exec bash -c 'myfile {}' \;
我设法以更优雅的方式运行它:
function myfile { ... }
export -f myfile
find -name out.ogv -exec bash -c '"$@"' myfile myfile '{}' \;
请注意,
myfile
出现了两次。第一个是脚本的 $0
参数(在这种情况下它基本上可以是任何东西)。第二个是要运行的函数的名称。
$ 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?
$
当然,函数可能比我的示例稍微复杂一些。
您可以通过将命令放入 bash 的 StdIn 中来让 bash 运行函数:
bash$ find ./ -name *.ogv -exec echo myfile {} \; | bash
上面的命令适用于您的示例,但是您需要注意以下事实:所有“
myfile...
”命令都是立即生成并发送到单个 bash 进程。
我不认为
find
可以做到这一点,因为正在执行的是 find
命令本身
命令,而不是您当前正在运行的 shell...所以 bash 函数或别名
不会在那里工作。如果你把你的函数定义变成一个单独的
名为 myfile
的 bash 脚本,使其可执行,并将其安装在您的路径上的某个位置,
find
应该用它做正确的事情。
更简单
function myfile { echo $* ; }
export -f myfile
find . -type f -exec bash -c 'myfile "{}"' \;
子 shell 脚本似乎保留了父函数,因此您可以编写类似于此的脚本:
'runit.sh'
#! /bin/bash
"$@"
然后做
find -name out.ogv -exec ./runit.sh myfile '{}' \;
它有效! :)
谢谢若奥。这看起来是非常聪明和优雅的解决方案。小问题是我必须首先获取脚本才能运行 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
无论如何,非常感谢。
这个 oneliner 应该适合我的情况:
find . -name *.ogv -exec bash -c 'myfile {}' \;