对`find`-sh的结果执行功能

时间:2019-05-10 16:12:41

标签: linux shell alpine

我正在编写一个外壳脚本,以在基于Alpine的docker映像上运行。它的外壳是/bin/sh

我想做的是为find命令的结果执行一个函数。以下在我的本地bashsh shell中起作用。

myscript.sh:

#!/bin/sh

function get_tags {
  # do stuff
}


export -f get_tags

# get all YAML files in ./assets/config that have 'FIND' somewhere in the filename
# pass each to the get_tags function
find ./assets/config -type f \( -iname "Find*.yaml" -or -iname "Find*.yml" \) -exec sh -c 'get_tags "$0"' {} \;

但是,当我在高山图像上运行它时,出现以下错误:

./myscript.sh: export: line 31: illegal option -f

还有其他方法可以做到吗?

我的问题不是“ shbash之间有什么区别”。我的问题是:如何完成在find命令的输出上运行功能的任务。

2 个答案:

答案 0 :(得分:1)

您需要使用bash,如下所示:

#!/bin/bash
fun() { echo "fun ${1}" ; }
export -f fun
find . -name 'foo' -exec bash -c 'fun "${1}"' -- {} \;

此处的关键是运行bash -c 'fun "${1}"' -- {} \;。您不能直接调用该函数(并向其传递参数)。您需要将其包装到一个最小脚本中,该最小脚本将接收find传递的参数并将其传递给函数。


注意:我正在向bash -c传递两个参数:字符串--和实际文件名{}。我按照惯例进行操作,因为当脚本由$0执行时,参数计数从bash -c开始,而与以常规方式运行脚本(在文件中,不是通过$1

bash -c可以工作,但是人们可能会认为bash -c 'fun "${0}"' {} \;是脚本名称,就像他们从普通脚本中知道的一样。

答案 1 :(得分:1)

导出功能是一项Bash功能。 Bash不附带Alpine Linux。

您可以改为使用while read循环来处理结果,因为这是POSIX,并且可以在所有shell上使用:

get_tags() {
  echo "Getting tags for $1"
}

find ./assets/config -type f \( -iname "Find*.yaml" -o -iname "Find*.yml" \) |
    while IFS="" read -r file
    do
      get_tags "$file"
    done