Accessing docker-cli string array element in Go templates

520 Views Asked by At

I created a docker container but cannot seem to parse its properties with docker-cli and its format parameter (which uses Go templates).

Any idea greatly appreciated.

  1. Start a docker container, e.g. go to https://birthday.play-with-docker.com/cli-formating/ and click on the docker command in the Prepare the environment section

  2. Choose a property for parsing, e.g. Ports. Printing it with docker container ls --format '{{ .Ports }}' should yield 0.0.0.0:80->80/tcp.

  3. Trying to get the port range part after the colon, split the property at ":" (docker container ls --format '{{ split .Ports ":" }}') which yields array [0.0.0.0 80->80/tcp]

  4. The return type (docker container ls --format '{{ printf "%T" (split .Ports ":") }}') is []string.

  5. The string array has a length of 2 (docker container ls --format '{{ len (split .Ports ":") }}') .

  6. Accessing index value 0 (docker container ls --format '{{ index (split .Ports ":") 0 }}') yields 0.0.0.0 as expected.

  7. Accessing index value 1 (docker container ls --format '{{ index (split .Ports ":") 1 }}') yields failed to execute template: template: :1:2: executing "" at <index (split .Ports ":") 1>: error calling index: reflect: slice index out of range instead of 80->80/tcp .

1

There are 1 best solutions below

0
Marcuse7 On

In order to access string array elements, I found a solution. As this question focuses on the Go templates part in the --format parameter, I will just write about that.

The {{ index (split .Ports ":") 1 }} yields an error because index simply is the wrong function in this case. To access an array element, use slice:

  1. Access the second array element (zero-based index) with {{ slice (split .Ports ":") 1 }}, this yields [80->80/tcp].

  2. If you need string output, you can convert the slice object with join using "" as separator, removing the square brackets in the output: {{ join ( slice (split .Image ":") 1 ) "" }} yields 80->80/tcp.

The complete command is docker container ls --format '{{ join ( slice ( split .Ports ":" ) 1 ) "" }}'. Keep in mind that Go templates use a kind of prefix notation which might not seem that common.