在 `find` 的结果上执行函数 - sh
在 `find` 的结果上执行函数 - sh
我正在编写一个shell脚本,要在基于Alpine的Docker镜像上运行。它的shell是/bin/sh
。\n我试图做的是对find
命令的结果执行一个函数。以下内容在我的本地bash
和sh
shells中都有效。\nmyscript.sh:\n
#!/bin/sh function get_tags { # do stuff } export -f get_tags # 获取./assets/config目录中所有文件名中包含'FIND'的YAML文件 # 将每个文件传递给get_tags函数 find ./assets/config -type f \( -iname "Find*.yaml" -or -iname "Find*.yml" \) -exec sh -c 'get_tags "$0"' {} \;
\n然而,当我在Alpine镜像上运行它时,我得到以下错误:\n./myscript.sh: export: line 31: illegal option -f
\n我还有其他的方法吗?\n我的问题不是\"sh\"和\"bash\"之间的区别是什么。我的问题是:如何实现在find
命令的输出上运行一个函数的任务。
问题出现的原因是在使用find命令执行函数时,无法直接调用函数并传递参数。需要将函数包装在一个最小的脚本中,并通过find命令传递参数给该脚本。
解决方法是使用bash命令,并通过bash -c 'fun "${1}"' -- {} \;的方式来执行函数。其中,{}表示find命令的结果,通过--和{}作为参数传递给bash命令中的fun函数。这样做是因为当通过bash -c执行脚本时,参数计数从$0开始,而不是从$1开始。
需要注意的是,为了避免混淆,我们在bash -c命令中传递了两个参数:字符串--和实际的文件名{}。虽然使用bash -c 'fun "${0}"' {} \;也可以工作,但是人们可能会错误地认为$0是脚本的名称,这与正常脚本的执行方式不同。
另外,在评论中建议安装bash,这也是解决该问题的一个步骤。
在上述内容中,问题的出现原因是Alpine Linux不支持Bash,而Bash中的一个特性是可以导出函数。解决方法是使用一个“while read”循环来处理结果,因为这是POSIX标准,适用于所有的shell。具体的解决方法如下:
get_tags() { echo "获取 $1 的标签" } find ./assets/config -type f \( -iname "Find*.yaml" -o -iname "Find*.yml" \) | while IFS="" read -r file do get_tags "$file" done
通过上述代码,可以实现对指定目录下的文件进行查找,并对每个文件调用`get_tags`函数进行处理。