首页 > 解决方案 > shell 脚本(busybox)在 docker 容器上不能按预期工作

问题描述

使用 busybox 和 ash 运行基于图像的 alpine:

/mnt/builddir/code/src/main/helm # busybox | head -1
BusyBox v1.31.1 () multi-call binary.

我编写了一个 sh 脚本,仅当文件名以前缀“values”开头时才打印文件名,但带有“if”条件的东西不能很好地工作。这是我的脚本:

for f in ./*
do
  echo ${f##*/}
  if ${f##*/} == 'values'*; then
      echo $f
  fi
done

输出:

/mnt/builddir/code/src/main/helm # ./script.sh
Chart.yaml
./script.sh: line 4: Chart.yaml: not found
script.sh
./script.sh: line 4: script.sh: not found
values-feature.yaml
./script.sh: line 4: values-feature.yaml: not found
values-int.yaml
./script.sh: line 4: values-int.yaml: not found
values-prod.yaml
./script.sh: line 4: values-prod.yaml: not found
values-stg.yaml
./script.sh: line 4: values-stg.yaml: not found
values.yaml
./script.sh: line 4: values.yaml: not found

在我将代码更改为上述代码之前,if 条件如下所示:

if [[ ${f##*/} == values* ]]
then
    ...

但这也不起作用。

谢谢你的建议...

标签: dockershellshbusybox

解决方案


该脚本有两个明显的问题:在您的if行中,您没有调用test (1),而是直接尝试运行每个文件;并且test (1)==运算符只进行精确的字符串比较,而不是 glob 或正则表达式匹配。

您可以使用 shellcase语句将变量与 glob 进行匹配:

case "$f" in
  */values*)
    echo "$f"
    ;;
esac

但是 shellfor语句可以遍历 glob 扩展,这将是一个通常更简单的设置:

for f in values*; do
  echo "$f"
done

(这根本不是 Docker 特有的,我希望您直接在主机上运行脚本会遇到非常相似的错误。您可能会发现在没有 Docker 作为隔离层的情况下开发和调试脚本要容易得多您和您要修复的代码。)


推荐阅读