Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exit code from docker-compose breaking while loop

I've got case: there's WordPress project where I'm supposed to create a script for updating plugins and commit source changes to the separated branch. While doing this I had run into a strange issue.

Input variable:

    akimset,4.0.3
    all-in-one-wp-migration,6.71

What I wanted to do was iterating over each line of this variable

    while read -r line; do
      echo $line
    done <<< "$variable"

and this piece of code worked perfectly fine, but when I have added docker-compose logic everything started to act weirdly

    while read -r line; do
      docker-compose run backend echo $line
    done <<< "$variable"

now only one line was executed and after this script exited with 0 and stopped iterating. I have found workaround with:

    echo $variable > file.tmp
    for line in $(cat file.tmp); do
      docker-compose run backend echo $line
    done

and that works perfectly fine and it iterates each line. Now my question is: why? ZSH and shell scripting could be a bit misterious and running in edge-cases like this one isn't anything new for me, but I'm wondering why succesfully executed script broke input stream.

like image 742
Mikołaj Młodzikowski Avatar asked Oct 14 '25 09:10

Mikołaj Młodzikowski


2 Answers

The problem with this

while read -r line; do
  docker-compose run backend echo $line
done <<< "$variable"

is that docker allocate pseudo-TTY. After the first execution of docker-compose run (first loop) it access to the terminal using up the next lines as input.

You have to pass -T parameter to 'docker-compose run' command in order to avoid docker allocating pseudo-TTY. Then, a working code is:

while read -r line; do
  docker-compose run -T backend echo $line
done < $(variable)

Update

The above solution is for docker version 18 and docker-compose version 1.17. For newer version the parameter -T is not working but you can try:

  1. -d instead of -T to run container in background mode BUT no you will not see stdout in terminal.
  2. If you have docker-compose v1.25.0, in your docker-compose.yml add the parameter stdin_open: false to the service.
like image 62
Andres Avatar answered Oct 18 '25 04:10

Andres


I was able to solve the same problem by using a different loop :

for line in $(cat $variable)
do
    docker-compose run backend echo $line
done
like image 40
wlarcheveque Avatar answered Oct 18 '25 04:10

wlarcheveque



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!