有没有办法找到执行我在shell中定义的函数?
例如:
dosomething () {
echo "Doing something with $1"
}
find . -exec dosomething {} \;
其结果是:
find: dosomething: No such file or directory
有没有办法让find's -exec看到做某事?
有没有办法找到执行我在shell中定义的函数?
例如:
dosomething () {
echo "Doing something with $1"
}
find . -exec dosomething {} \;
其结果是:
find: dosomething: No such file or directory
有没有办法让find's -exec看到做某事?
当前回答
为了对其他一些答案进行补充和澄清,如果您正在为exec或execdir (-exec命令{}+)使用bulk选项,并希望检索所有位置参数,则需要考虑使用bash -c处理$0。
更具体地说,考虑下面的命令,它使用上面建议的bash -c,并简单地从它找到的每个目录回显以'.wav'结尾的文件路径:
find "$1" -name '*.wav' -execdir bash -c 'echo "$@"' _ {} +
Bash手册说:
如果有-c选项,则从第一个非选项参数command_string中读取命令。如果在command_string之后有参数,则将它们分配给位置参数,从$0开始。
这里,'echo "$@"'是命令字符串,_{}是命令字符串之后的参数。注意,$@在Bash中是一个特殊的位置参数,它扩展到从1开始的所有位置参数。还要注意,使用-c选项时,第一个参数被分配给位置形参$0。
这意味着如果您尝试使用$@访问所有的位置参数,则只能获得$1及以上的参数。这就是为什么Dominik的答案有_,这是一个填充参数$0的哑参数,所以我们想要的所有参数都可以在以后使用,如果我们使用$@参数展开,或者在答案中使用for循环。
当然,类似于接受的答案,bash -c 'shell_function "$0" "$@"'也可以通过显式传递$0来工作,但同样,您必须记住$@不会像预期的那样工作。
其他回答
因为只有shell知道如何运行shell函数,所以必须运行shell才能运行函数。你还需要用export -f标记你的export函数,否则子shell不会继承它们:
export -f dosomething
find . -exec bash -c 'dosomething "$0"' {} \;
把函数放在一个单独的文件中,然后get find来执行它。
Shell函数在定义它们的Shell内部;Find永远也看不到他们。
Jac的回答很好,但它有几个容易克服的陷阱:
find . -print0 | while IFS= read -r -d '' file; do dosomething "$file"; done
这将使用null作为分隔符而不是换行符,因此具有换行符的文件名将正常工作。它还使用-r标志来禁用反斜杠转义,如果没有它,文件名中的反斜杠将不起作用。它还清除IFS,以便名称中潜在的尾随空白不会被丢弃。
为了对其他一些答案进行补充和澄清,如果您正在为exec或execdir (-exec命令{}+)使用bulk选项,并希望检索所有位置参数,则需要考虑使用bash -c处理$0。
更具体地说,考虑下面的命令,它使用上面建议的bash -c,并简单地从它找到的每个目录回显以'.wav'结尾的文件路径:
find "$1" -name '*.wav' -execdir bash -c 'echo "$@"' _ {} +
Bash手册说:
如果有-c选项,则从第一个非选项参数command_string中读取命令。如果在command_string之后有参数,则将它们分配给位置参数,从$0开始。
这里,'echo "$@"'是命令字符串,_{}是命令字符串之后的参数。注意,$@在Bash中是一个特殊的位置参数,它扩展到从1开始的所有位置参数。还要注意,使用-c选项时,第一个参数被分配给位置形参$0。
这意味着如果您尝试使用$@访问所有的位置参数,则只能获得$1及以上的参数。这就是为什么Dominik的答案有_,这是一个填充参数$0的哑参数,所以我们想要的所有参数都可以在以后使用,如果我们使用$@参数展开,或者在答案中使用for循环。
当然,类似于接受的答案,bash -c 'shell_function "$0" "$@"'也可以通过显式传递$0来工作,但同样,您必须记住$@不会像预期的那样工作。
我发现最简单的方法如下,一次重复两个命令:
func_one () {
echo "The first thing with $1"
}
func_two () {
echo "The second thing with $1"
}
find . -type f | while read file; do func_one $file; func_two $file; done