Issue in executing docker command in bash script - bash

I have following bash script code try to run a docker container through bash script but I am retreiving error.
#!/bin/bash
name=sudo docker ps | grep 'test' | awk '{print
$1}'
sudo docker exec -it $name bash
error:
docker exec requires at least two arguments

Assuming that you have a docker container actually called test running, the way the id is attained is incorrect. In order to expand a command into a variable, it needs to be contained within $() and so:
#!/bin/bash
name=$(docker ps | grep 'test' | awk '{print $1}')
sudo docker exec -it $name bash
A further note is the fact that you don't need sudo permissions to run docker ps ...
Additionally, you never need to pipe grep into awk as awk can do this for you:
name=$(docker ps | awk '/test/ {print $1}')
Further more, there is no need to pipe at all given the native capabilities built into docker-ps and so:
name=$(docker ps -q -f name=test)
This will print only the container id of a container named test. I'm assuming that the name is test here but it could be something else i.e. the label that is named test, in which case the filter would need to change:
-f, --filter=[]
Filter output based on these conditions:
- exited=<int> an exit code of <int>
- label=<key> or label=<key>=<value>
- status=(created|restarting|running|paused|exited|dead)
- name=<string> a container's name
- id=<ID> a container's ID
- before=(<container-name>|<container-id>)
- since=(<container-name>|<container-id>)
- ancestor=(<image-name>[:tag]|<image-id>| â¨image#digestâ©) - conâ
tainers created from an image or a descendant.
- volume=(<volume-name>|<mount-point-destination>)
- network=(<network-name>|<network-id>) - containers connected to
the provided network

Related

how to pass container id to docker exec through output of another cmd

i want to pass docker container id from output of another linux command
example (as pseudo-code):
save output of docker ps cmd to a file
docker ps > docker.log
grep only container id : awk 'FNR == 2{print $1}'
now i want to pass the output of awk cmd to docker exec
like docker exec -it awk 'FNR == 2{print $1}' /bin/bash (i am not able to pass container id through cmd)
this is to automate a process that needs ssh in docker containers
Why not something like this:
docker exec -it $(docker ps | grep dac705114996 | awk '{print $1}') /bin/sh
As you can see, in order to pass the container-id to the docker exec cmd, you need to substitute the container-id with $(command that extracts the container-id) Command Substitution (more official docs)

How to obtain container id base on docker image name via command line ?

If I ran sudo doccker ps I got this
[user#vm1 ~]$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e8ff73dec1d5 portal-mhn:latest "nginx -g 'daemon of…" 43 minutes ago Up 43 minutes portal-mhn_portal-mhn.1.4rsfv94wy97gb333q3kfyxz32
62a7cf09d7bf portal-admin:latest "nginx -g 'daemon of…" 43 minutes ago Up 43 minutes portal-admin_portal-admin.1.s62iep4gl5g5oj2hrap14kz1t
I'm trying to grab the container ID base on ImageName.
Ex. Is there away to grab the container id of portal-mhn:latest via a command line ? which is e8ff73dec1d5
If you want to get the container id based on the image name this should work:
$ docker ps | grep '<image_name>' | awk '{ print $1 }'
Or even:
$ docker ps | awk '/<image_name>/ { print $1 }'
As others have suggested you can also directly filter by the image name using the ancestor filter:
$ docker ps -aqf "ancestor=<image_name>"
Thanks to #kevin-cui and #yu-chen.
The accepted answer works, but you might possibly have a misnamed container name that has postgres in its name but is actually running a totally different image, since the answer only uses grep to look for matching lines.
You can use Docker's built in filter flag:
docker ps --filter "ancestor=postgres" -q
as an alternative. The -q flag indicates to only return the container ID (quiet mode).
I needed only to obtain the latest running container id by image name, including stopped containers:
docker ps -a | grep 'django-content-services:' -m 1 | awk '{ print $1 }'
In docker -a to include all containers (even stopped). In grep, -m so grep only matches the first case. Cheers!

Grep on docker image names in package.json

I want to set a script in the package.json that starts the container based on image-name that I grep after piping the docker images command, something like this:
"docker:run": "docker run -it -v /$(pwd):/app $(docker images | grep 'online-check-in-frontend' | awk '{ print $1 }') sh",
also tried :
"docker:run": "docker run -it -v /$(pwd):/app $(docker images | grep \"online-check-in-frontend\" | awk \"{ print $1 }\") sh",
The commands above is not working, i get the following error:
Im using windows, and bash. :S
Br

Shell : How to get a container's name containing some string

I have a list of containers where names are like following :
container 1: myApp_ihm.dfgdfgdfgdfvdfdfbvdfvdfv
container 2: myApp_back.uirthjhiliszfhjuioomlui
...
container 3: myApp_database.piyrjfhjyukyujfkgft
I have to execute some string on the container where the name contains ihm (the first one in my example)
In order to exec my commands , I'm used to do:
docker exec -it ihm bash
so ihm should by replaced by some test to get the first one name :
myApp_ihm.dfgdfgdfgdfvdfdfbvdfvdfv
Suggestions?
docker exec -it $(docker ps | grep myApp_ihm | awk '{print $1}') /bin/bash
docker exec -it $(docker ps --format "{{.Names}}" | grep "ihm") bash
This worked for me, added that to a bash script and saved myself 30-60 seconds of typing/copy-pasting every time I want to go into my container.
docker exec -it $(docker ps --format "{{.ID}} {{.Command}}" | grep /home/app/ | awk '{print $1}') /bin/bash

Get Environment Variable from Docker Container

What's the simplest way to get an environment variable from a docker container that has not been declared in the Dockerfile?
For instance, an environment variable that has been set through some docker exec container /bin/bash session?
I can do docker exec container env | grep ENV_VAR, but I would prefer something that just returns the value.
I've tried using docker exec container echo "$ENV_VAR", but the substitution seems to happen outside of the container, so I don't get the env var from the container, but rather the env var from my own computer.
Thanks.
To view all env variables:
docker exec container env
To get one:
docker exec container env | grep VARIABLE | cut -d'=' -f2
The proper way to run echo "$ENV_VAR" inside the container so that the variable substitution happens in the container is:
docker exec <container_id> bash -c 'echo "$ENV_VAR"'
You can use printenv VARIABLE instead of /bin/bash -c 'echo $VARIABLE. It's much simpler and it does not perform substitution:
docker exec container printenv VARIABLE
The downside of using docker exec is that it requires a running container, so docker inspect -f might be handy if you're unsure a container is running.
Example #1. Output a list of space-separated environment variables in the specified container:
docker inspect -f \
'{{range $index, $value := .Config.Env}}{{$value}} {{end}}' container_name
the output will look like this:
ENV_VAR1=value1 ENV_VAR2=value2 ENV_VAR3=value3
Example #2. Output each env var on new line and grep the needed items, for example, the mysql container's settings could be retrieved like this:
docker inspect -f \
'{{range $index, $value := .Config.Env}}{{println $value}}{{end}}' \
container_name | grep MYSQL_
will output:
MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=supersecret
MYSQL_USER=demo
MYSQL_DATABASE=demodb
MYSQL_MAJOR=5.5
MYSQL_VERSION=5.5.52
Example #3. Let's modify the example above to get a bash friendly output which can be directly used in your scripts:
docker inspect -f \
'{{range $index, $value := .Config.Env}}export {{$value}}{{println}}{{end}}' \
container_name | grep MYSQL
will output:
export MYSQL_PASSWORD=secret
export MYSQL_ROOT_PASSWORD=supersecret
export MYSQL_USER=demo
export MYSQL_DATABASE=demodb
export MYSQL_MAJOR=5.5
export MYSQL_VERSION=5.5.52
If you want to dive deeper, then go to Go’s text/template package documentation with all the details of the format.
Since we are dealing with JSON and unlike the accepted answer, we don't need to exec the container.
docker inspect <NAME|ID> | jq '.[] | .Config.Env'
Output sample
[
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.19.4",
"NJS_VERSION=0.4.4",
"PKG_RELEASE=1~buster"
]
To retrieve a specific variable
docker inspect <NAME|ID> | jq -r '.[].Config.Env[]|select(match("^<VAR_NAME>"))|.[index("=")+1:]'
See jq
None of the above answers show you how to extract a variable from a non-running container (if you use the echo approach with run, you won't get any output).
Simply run with printenv, like so:
docker run --rm <container> printenv <MY_VAR>
(Note that docker-compose instead of docker works too)
If by any chance you use VSCode and has installed the docker extension, just right+click on the docker you want to check (within the docker extension), click on Inspect, and there search for env, you will find all your env variables values
We can modify entrypoint of a non-running container with the docker run command.
Example show PATH environment variable:
using bash and echo: This answer claims that echo will not produce any output, which is incorrect.
docker run --rm --entrypoint bash <container> -c 'echo "$PATH"'
using printenv
docker run --rm --entrypoint printenv <container> PATH
#aisbaa's answer works if you don't care when the environment variable was declared. If you want the environment variable, even if it has been declared inside of an exec /bin/bash session, use something like:
IFS="=" read -a out <<< $(docker exec container /bin/bash -c "env | grep ENV_VAR" 2>&1)
It's not very pretty, but it gets the job done.
To then get the value, use:
echo ${out[1]}
This command inspects docker stack processes' environment in the host :
pidof dockerd containerd containerd-shim | tr ' ' '\n' \
| xargs -L1 -I{} -- sudo xargs -a '/proc/{}/environ' -L1 -0
The first way we use to find the ENV variables is docker inspect <container name>
The second way is docker exec <4 alphanumeric letter of CONTAINER id> bash -c 'echo "$ENV_VAR"'
There is a misconception in the question, that causes confusion:
you cannot access a "running session", so no bash session can change anything.
docker exec -ti container /bin/bash
starts a new console process in the container, so if you do export VAR=VALUE this will go away as soon as you leave the shell, and it won't exist anymore.
Perhaps a good example:
# assuming TESTVAR did not existed previously this is empty
docker exec container env | grep TESTVAR
# -> TESTVAR=a new value!
docker exec container /bin/bash -c 'TESTVAR="a new value!" env' | grep TESTVAR
# again empty
docker exec container env | grep TESTVAR
The variables from env come from the Dockerfile or command, docker itself and whatever the entrypoint sets.
The other answers here are good. But if you really need to get the environmental properties used when starting a program, then you can inspect the /proc/pid/environ contents in the container, where pid is the container process id of the running comand.
# environmental props
docker exec container cat /proc/pid/environ | tr '\0' '\n'
# you can check this is the correct pid by checking the ran command
docker exec container cat /proc/pid/cmdline | tr '\0' ' '

Resources