我正在编写一个基于Alpine的Docker图像上运行的Shell脚本。它的外壳是/bin/sh
。
我要做的是为find
命令的结果执行功能。以下在我的本地bash
和sh
壳中工作。
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
命令的输出上运行功能的任务。
您需要使用bash
,例如:
#!/bin/bash
fun() { echo "fun ${1}" ; }
export -f fun
find . -name 'foo' -exec bash -c 'fun "${1}"' -- {} ;
这里的关键是运行bash -c 'fun "${1}"' -- {} ;
。您不能直接调用该函数(并将参数传递给它(。您需要将其包装成一个最小的脚本,在该脚本中,此最小脚本接收到通过查找的参数并将其传递到函数。
注意:我将两个参数传递给bash -c
:字符串--
和实际文件名{}
。我正在按照惯例进行此操作,因为当脚本由bash -c
执行时,参数计数从$0
开始,与$1
相反,在运行脚本时(在文件中,不是通过bash -c
(
bash -c 'fun "${0}"' {} ;
会起作用,但是人们可能会认为 $0
是他们从普通脚本中知道的脚本名称。
导出功能是bash功能。Alpine Linux不带Bash。
您可以使用while read
循环处理结果,因为这是Posix,并且将在所有外壳上工作:
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