有没有办法找到执行我在shell中定义的函数?

例如:

dosomething () {
  echo "Doing something with $1"
}
find . -exec dosomething {} \;

其结果是:

find: dosomething: No such file or directory

有没有办法让find's -exec看到做某事?


当前回答

批量处理结果

为了提高效率,许多人使用xargs批量处理结果,但这是非常危险的。因此,在find中引入了另一种方法来批量执行结果。

但是请注意,这种方法可能会带来一些警告,例如POSIX-find中要求在命令末尾使用{}。

export -f dosomething
find . -exec bash -c 'for f; do dosomething "$f"; done' _ {} +

Find会将许多结果作为参数传递给一次bash调用,for循环遍历这些参数,执行函数对每个参数执行一些操作。

上面的解决方案从$1开始参数,这就是为什么有_(代表$0)。

逐一处理结果

同样地,我认为公认的最上面的答案应该更正为

export -f dosomething
find . -exec bash -c 'dosomething "$1"' _ {} \;

这不仅更明智,因为参数应该总是以$1开始,而且如果find返回的文件名对shell具有特殊含义,则使用$0可能会导致意外的行为。

其他回答

我会完全避免使用-exec。使用xargs:

find . -name <script/command you're searching for> | xargs bash -c

在{}中添加引号,如下所示:

export -f dosomething
find . -exec bash -c 'dosomething "{}"' \;

这将纠正由于find返回的特殊字符而导致的任何错误, 例如文件名中带有圆括号的文件。

让脚本调用自身,将找到的每个项作为参数传递:

#!/bin/bash

if [ ! $1 == "" ] ; then
   echo "doing something with $1"
   exit 0
fi

find . -exec $0 {} \;

exit 0

当您单独运行脚本时,它会找到您正在寻找的内容,并调用自己,将每个查找结果作为参数传递。当脚本使用参数运行时,它会执行参数上的命令,然后退出。

因为只有shell知道如何运行shell函数,所以必须运行shell才能运行函数。你还需要用export -f标记你的export函数,否则子shell不会继承它们:

export -f dosomething
find . -exec bash -c 'dosomething "$0"' {} \;

批量处理结果

为了提高效率,许多人使用xargs批量处理结果,但这是非常危险的。因此,在find中引入了另一种方法来批量执行结果。

但是请注意,这种方法可能会带来一些警告,例如POSIX-find中要求在命令末尾使用{}。

export -f dosomething
find . -exec bash -c 'for f; do dosomething "$f"; done' _ {} +

Find会将许多结果作为参数传递给一次bash调用,for循环遍历这些参数,执行函数对每个参数执行一些操作。

上面的解决方案从$1开始参数,这就是为什么有_(代表$0)。

逐一处理结果

同样地,我认为公认的最上面的答案应该更正为

export -f dosomething
find . -exec bash -c 'dosomething "$1"' _ {} \;

这不仅更明智,因为参数应该总是以$1开始,而且如果find返回的文件名对shell具有特殊含义,则使用$0可能会导致意外的行为。