简体   繁体   中英

Looping over arguments in bash array for docker commands?

I seem to be stuck here. I'm attempting to write a bash function that starts x number of docker containers, wish an array that holds exposed ports for the given app. I don't want to loop over the array, just the commands, while referencing the array to get the value. The function looks like this:

#!/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
  }

And I want to pass arguments like so:

./script.sh start app1 app2 app4

Right now it isn't echoing the app so that points towards the for loop being declared incorrectly...could use some pointers on this.

This line:

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

doesn't do what you want. It looks like you mean to say:

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

but you could fail to detect two copies of the application running, and you aren't looking for the application as a word (so if you look for rm you might find perform running and think rm was running).

You should consider, therefore, using:

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

This runs the docker command and pipes the result to grep , and reports on the exit status of grep . The -w looks for a word containing the value of "$app" , but does so quietly ( -q ), so grep only reports success (exit status 0 ) if it found at least one matching line or failure (non-zero exit status) otherwise.

docker ps -f lets you conveniently check programmatically whether a particular image is running.

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

Unfortunately, docker ps does not set its exit code (at least not in the versions I have available -- I think it has been fixed in some development version after 17.06 but I'm not sure) so we have to use an ugly pipe to grep -q . to check whether the command produced any output. The -q flag just minimizes the amount of stuff it prints (it will print just the container ID instead of a bunch of headers and columnar output for each matching container).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM