Also, can somebody fully explain me how this block of code exactly works? I didn . . .

LordSilver:
Also, can somebody fully explain me how this block of code exactly works? I didn’t even know an unless instruction existed in bash.

docker image ls | perl -lane 'print "docker run --rm $F[0]:$F[1] cat /etc/os-release" unless /REPOSITORY/' | sh | grep PRETTY

Source: https://stackoverflow.com/questions/35689431/determine-os-distribution-of-a-docker-image

Alistair Mackay:
docker image ls - list all the images you have
'print "docker run --rm $F[0]:$F[1] cat /etc/os-release" unless /REPOSITORY/' is a PERL script. This perl script will print, for each line of input from docker image ls a command to run the image and print the contents of /etc/os-release from in the container unless the input line contains REPOSITORY
| sh - for each line output by the perl script, execute it with the shell
| grep PRETTY - from the previous output of each docker run which has multiple lines, select the one with PRETTY in.
Bash doesn’t have unless - Perl does.

LordSilver:
Btw, I used that command from StackOverflow to answer one of the questions in the KodeKloud lab since I didn’t want to create a container. I noticed that when you use docker inspect there’s actually an entry called “Os: Linux” but it didn’t specify that it was using Debian OS. The command from StackOverflow still “cheats” as it actually creates a container and then destroys it.

LordSilver:
I found out you can actually retrieve what OS an image uses without running a container instance, but it’s quite inconvenient: https://stackoverflow.com/questions/63785595/how-to-find-out-which-linux-is-installed-inside-docker-image

Alistair Mackay:
docker create will create a container without actually starting it (i.e it is in stopped state). This means you can access its file system to copy files out with docker cp
Still, the easiest way to determine the release is to run it and cat /etc/os-release and would be sufficient for an exam unless you are explicitly told not to run it.

LordSilver:
Ok, I was actually wondering what would be the “best way” to do it since KodeKloud didn’t show it in the video course.

Alistair Mackay:
The best way is the easiest way :wink:
You’re unlikely to be asked to identify the OS in every image that’s downloaded locally unless it’s only one or 2, i.e. have to remember the perl script to get all results quickly.

LordSilver:
In that case, the solution of the guy with the Pearl script would be the best, since that automatically goes through your list of images and list the OS for each one.

Alistair Mackay:
So if you were asked to do it for e.g. image nginx:1.19 then it would be

docker run --rm nignx:1.19 cat /etc/os-release

LordSilver:
Could you explain the $F[0]:$F[1] part btw?

LordSilver:
I won’t remember that command for sure and I will just be running each container individually, but I’d still like to understand it.

Alistair Mackay:
The perl script is splitting the image name into fields
$F[0} is the name (nignx)
$F[1] is the tag (1.19)

so the one-liner you originally asked about is forming the image:tag for every image in the local repo and running docker run --rm .. on it

LordSilver:
But why $F? Is it the variable type?

Alistair Mackay:
So if you had nginx.1.19 and busybox:1.27 then the script would generate and execute

docker run --rm  nignx:1.19 cat /etc/os-release
docker run --rm  busybox:1.27 cat /etc/os-release

$F is a array containing the fields split around :

The same script could probably be done with awk or maybe even pure bash but would be more complex.