在bash数组中为docker命令循环参数?

我似乎被困在这里。 我试图写一个bash函数启动x数量的docker集装箱,希望一个arrays,持有暴露的端口为给定的应用程序。 我不想循环数组,只是命令,而引用数组来获取值。 该函数如下所示:

 #!/bin/bash declare -a HOSTS=( ["app1"]="8002" ["app2"]="8003" ["app3"]="8008" ["app4"]="8009" ["app5"]="8004" ["app6"]="8007" ["app7"]="8006" ) start() { for app in "$@"; do if [ "docker ps|grep $app" == "$app" ]; then docker stop "$app" fi docker run -it --rm -d --network example_example \ --workdir=/home/docker/app/src/projects/"$app" \ --volume "${PWD}"/example:/home/docker/app/src/example \ --volume "${PWD}"/projects:/home/docker/app/src/projects \ --volume "${PWD}"/docker_etc/example:/etc/example \ --volume "${PWD}"/static:/home/docker/app/src/static \ --name "$app" --hostname "$app" \ --publish "${HOSTS["$app"]}":"${HOSTS["$app"]}" \ example ./manage.py runserver 0.0.0.0:"${HOSTS[$app]}"; echo "$app" done } 

我想传递这样的参数:

./script.sh start app1 app2 app4

现在它没有回应应用程序,因此指向for循环被错误地声明…可以使用一些指针。

这一行:

 if [ "docker ps|grep $app" == "$app" ]; 

没有做你想做的事。 看起来你的意思是说:

 if [ "$(docker ps | grep "$app")" == "$app" ]; 

但是你可能无法检测到运行的应用程序的两个副本,而且你不是在寻找应用程序作为一个单词(所以如果你寻找rm你可能会发现perform运行,认为rm正在运行)。

因此,您应该考虑使用:

 if docker ps | grep -w -q "$app" then … fi 

这将运行docker命令并将结果传递给grep ,并报告grep的退出状态。 -w查找包含"$app"值的单词,但是这样静静地执行( -q ),所以如果grep发现至less有一个匹配的行或失败(非零退出),则只报告成功(退出状态0 )状态),否则。

docker ps -f让你方便地通过编程方式检查一个特定的图像是否正在运行。

 for app in "$@"; do if docker ps -q -f name="$app" | grep -q .; then docker stop "$app" : 

不幸的是, docker ps没有设置它的退出代码(至less在我没有提供的版本中 – 我认为已经在17.06之后的一些开发版本中修复了,但是我不确定),所以我们必须使用一个丑陋的pipe道grep -q . 检查命令是否产生任何输出。 -q标志只是最小化它打印的东西的数量(它将只打印容器ID,而不是每个匹配容器的一堆标题和列输出)。