SPIRiT_1984
SPIRiT_1984

Reputation: 2787

Why does bash script work depend on the size of the terminal window?

I know this sounds strange, but here is the thing. I have a docker container, that hosts a database. And I have a script, that tries to execute a set a patches over it one by one. Now, the script does not know the database port (since each time the container binds to a different port). So here is the beginning of the script:

#!bin/bash

echo "Calculating the port..."
port=$(docker-compose ps | grep database-docker | sed  "s/.*://g" | sed "s/\-.*//")
echo "Port is $port"

Basically it's supposed to react on the output of docker-compose ps, that outputs something like this:

     Name                       Command             State            Ports          
wildfly_database-docker_1   docker-entrypoint.sh mysqld   Up      0.0.0.0:32768->3306/tcp

But, here is the thing. If my terminal window is small, this script does not work, the port variable is empty. If I expand terminal window at full screen, it works fine, and does what I need. I guess that's because the output in the first case is broken in several lines, and it cannot be parsed correctly.

So, how to make bash script work independently of the window size?

UPD. I found the solution thanks to the comment. It seems like this is an issue of docker-compose. But after I change it to this line

port=$(docker ps | grep database-docker | sed  "s/.*://g" | sed "s/\-.*//") 

Everything works fine. Docker itself is not affected by the terminal size.

Upvotes: 0

Views: 551

Answers (3)

BMitch
BMitch

Reputation: 264986

For your requirement, I'd recommend changing your command to:

port=$(docker-compose port database-docker 3306 | sed 's/.*://')

The docker port and related docker-compose port commands are used to return the requested published port for your selected container/service and internal port number.

Upvotes: 0

tripleee
tripleee

Reputation: 189820

docker ps has an option --no-trunc to avoid having it suppress too-wide output but if you are not producing wide output in the first place, it won't be necessary.

Avoid the useless grep etc by simply using the built-in facility for printing machine-readable output.

docker ps --filter "name=database-docker" --format '{{.Ports}}' |
sed 's/.*:\([1-9][0-9]*\)->.*/\1/'

See the fine documentation for details. The Go template documentation is also required for properly understanding the --format option. I imagine it should be possible to use that to remove the remaining sed snippet but I am not in a position to learn enough Go to actually do that right now.


The Docker cheat sheet has the following formula:

docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}'

However, I get the following error message:

Template parsing error: template: :1:37: executing "" at <.NetworkSettings.Por...>: map has no entry for key "NetworkSettings"

Upvotes: 0

SPIRiT_1984
SPIRiT_1984

Reputation: 2787

I found the solution thanks to the comment. It seems like this is an issue of docker-compose. But after I change it to this line

port=$(docker ps | grep database-docker | sed  "s/.*://g" | sed "s/\-.*//") 

Everything works fine. Docker itself is not affected by the terminal size.

Upvotes: 2

Related Questions