我正在编写一个外壳脚本,以在基于Alpine的docker映像上运行。它的外壳是/bin/sh
。
我想做的是为find
命令的结果执行一个函数。以下在我的本地bash
和sh
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
还有其他方法可以做到吗?
我的问题不是“ sh
和bash
之间有什么区别”。我的问题是:如何完成在find
命令的输出上运行功能的任务。
答案 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