在 `find` 的结果上执行函数 - sh

14 浏览
0 Comments

在 `find` 的结果上执行函数 - sh

我正在编写一个shell脚本,要在基于Alpine的Docker镜像上运行。它的shell是/bin/sh。\n我试图做的是对find命令的结果执行一个函数。以下内容在我的本地bashsh 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命令的输出上运行一个函数的任务。

0
0 Comments

问题出现的原因是在使用find命令执行函数时,无法直接调用函数并传递参数。需要将函数包装在一个最小的脚本中,并通过find命令传递参数给该脚本。

解决方法是使用bash命令,并通过bash -c 'fun "${1}"' -- {} \;的方式来执行函数。其中,{}表示find命令的结果,通过--和{}作为参数传递给bash命令中的fun函数。这样做是因为当通过bash -c执行脚本时,参数计数从$0开始,而不是从$1开始。

需要注意的是,为了避免混淆,我们在bash -c命令中传递了两个参数:字符串--和实际的文件名{}。虽然使用bash -c 'fun "${0}"' {} \;也可以工作,但是人们可能会错误地认为$0是脚本的名称,这与正常脚本的执行方式不同。

另外,在评论中建议安装bash,这也是解决该问题的一个步骤。

0
0 Comments

在上述内容中,问题的出现原因是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`函数进行处理。

0