在 Linux 中 find -exec 一个 shell 函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4321456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
find -exec a shell function in Linux?
提问by alxndr
Is there a way to get find
to execute a function I define in the shell? For example:
有没有办法find
执行我在 shell 中定义的函数?例如:
dosomething () {
echo "doing something with "
}
find . -exec dosomething {} \;
The result of that is:
结果是:
find: dosomething: No such file or directory
Is there a way to get find
's -exec
to see dosomething
?
有没有办法让find
的-exec
看dosomething
?
采纳答案by Adam Rosenfield
Since only the shell knows how to run shell functions, you have to run a shell to run a function. You also need to mark your function for export with export -f
, otherwise the subshell won't inherit them:
由于只有 shell 知道如何运行 shell 函数,因此您必须运行 shell 才能运行函数。您还需要使用 标记导出函数export -f
,否则子shell 将不会继承它们:
export -f dosomething
find . -exec bash -c 'dosomething "# dosomething.sh
dosomething () {
echo "doing something with "
}
dosomething
"' {} \;
回答by Laurence Gonsalves
Not directly, no. Find is executing in a separate process, not in your shell.
不直接,不。Find 在单独的进程中执行,而不是在您的 shell 中执行。
Create a shell script that does the same job as your function and find can -exec
that.
创建一个与您的函数完成相同工作的 shell 脚本,然后找到-exec
它。
回答by codaddict
It is not possible to executable a functionthat way.
不可能以这种方式执行函数。
To overcome this you can place your function in a shell script and call that from find
为了克服这个问题,您可以将您的函数放在一个 shell 脚本中并从 find
find . -exec dosomething.sh {} \;
Now use it in find as:
现在在 find 中使用它:
find . | while read file; do dosomething "$file"; done
回答by Angus
Put the function in a separate file and get find
to execute that.
将该函数放在一个单独的文件中并开始find
执行。
Shell functions are internal to the shell they're defined in; find
will never be able to see them.
Shell 函数在定义它们的 Shell 内部;find
将永远无法看到他们。
回答by Jac
export -f dosomething
find . -exec bash -c 'dosomething "{}"' \;
回答by Wagner
Add quotes in {}
as shown below:
添加引号,{}
如下所示:
find . -name <script/command you're searching for> | xargs bash -c
This corrects any error due to special characters returned by find
,
for example files with parentheses in their name.
这将纠正由 返回的特殊字符引起的任何错误find
,例如名称中带有括号的文件。
回答by Barry
I would avoid using -exec
altogether. Why not use xargs
?
我会-exec
完全避免使用。为什么不使用xargs
?
#!/bin/bash
if [ ! == "" ] ; then
echo "doing something with "
exit 0
fi
find . -exec find . -print0 | while IFS= read -r -d '' file; do dosomething "$file"; done
{} \;
exit 0
回答by Mike Maready
Have the script call itself, passing each item found as an argument:
让脚本调用自身,将找到的每个项目作为参数传递:
export -f dosomething
find . -exec bash -c 'for f; do dosomething "$f"; done' _ {} +
When you run the script by itself, it finds what you are looking for and calls itself passing each find result as the argument. When the script is run with an argument, it executes the commands on the argument and then exits.
当您自己运行脚本时,它会找到您要查找的内容并调用自己,将每个查找结果作为参数传递。当脚本使用参数运行时,它会执行参数上的命令,然后退出。
回答by pajamian
Jak's answer above is great but has a couple of pitfalls that are easily overcome:
上面 Jak 的回答很好,但有几个容易克服的陷阱:
export -f dosomething
find . -exec bash -c 'dosomething ""' _ {} \;
This uses null as a delimiter instead of a linefeed, so filenames with linefeeds will work. It also uses the -r
flag which disables backslash escaping, without it backslashes in filenames won't work. It also clears IFS
so that potential trailing whitespaces in names are not discarded.
这使用 null 作为分隔符而不是换行符,因此带有换行符的文件名将起作用。它还使用-r
禁用反斜杠转义的标志,如果没有它,文件名中的反斜杠将不起作用。它还清除IFS
以便不会丢弃名称中潜在的尾随空格。
回答by Dominik
Processing results in bulk
批量处理结果
For increased efficiency, many people use xargs
to process results in bulk, but it is very dangerous. Because of that there was an alternate method introduced into find
that executes results in bulk.
为了提高效率,很多人xargs
习惯于批量处理结果,但这是非常危险的。因此,引入了一种替代方法find
来批量执行结果。
Note though that this method might come with some caveats like for example a requirement in POSIX-find
to have {}
at the end of the command.
不过,请注意,这种方法可能附带像例如在POSIX-要求一些注意事项find
有{}
在命令结束。
find
will pass many results as arguments to a single call of bash
and the for
-loop iterates through those arguments, executing the function dosomething
on each one of those.
find
将许多结果作为参数传递给单个调用,bash
并且for
-loop 迭代这些参数,dosomething
对每个参数执行函数。
The above solution starts arguments at $1
, which is why there is a _
(which represents $0
).
上面的解决方案从 开始参数$1
,这就是为什么有 a _
(代表$0
)。
Processing results one by one
一一处理结果
In the same way, I think that the accepted top answer should be corrected to be
同样,我认为应将公认的最佳答案更正为
##代码##This is not only more sane, because arguments should always start at $1
, but also using $0
could lead to unexpected behavior if the filename returned by find
has special meaning to the shell.
这不仅更合理,因为参数应该始终以 开头$1
,而且$0
如果返回的文件名find
对 shell 具有特殊意义,using也可能导致意外行为。