Execute two commands with docker exec
In your first example, you are giving the
-c flag to
docker exec. That's an easy answer:
docker exec does not have a
In your second example, your shell is parsing this into two commands before Docker even sees it. It is equivalent to this:
if docker exec [id] cd /var/www/project
docker exec is run, and if it exits 0 (success),
composer install will try to run locally, outside of Docker.
What you need to do is pass both commands in as a single argument to
docker exec using a string. Then they will not be interpreted by a shell until already inside the container.
docker exec [id] "cd /var/www/project && composer install"
However, as you noted in the comments, this also does not work. That's because
cd is a shell builtin, and doesn't exist on its own. Trying to execute it as the initial command will fail. So the next step is to hand this off to a shell to execute.
docker exec [id] "bash -c 'cd /var/www/project && composer install'"
And finally, at this point the
&& has moved into an inner set of quote marks, so we don't really need the quotes around the
bash command... you can drop them if you prefer.
docker exec [id] bash -c 'cd /var/www/project && composer install'
How to run 2 commands with docker exec
This led to the answer: Escape character in Docker command line
I ended up doing this:
sudo docker exec boring_hawking bash -c 'cd /var/log ; tar -cv ./file.log' | tar -x
So it works by, sort of, running the one bash command with a parameter that is the 2 commands I want to run.
Direct group of commands into `docker exec`
Use a here document.
docker run -i --rm alpine /bin/sh <<EOF
Note the difference between quoted and unquoted here document delimiter.
docker exec -i <id> /bin/sh < echo "echo 'foo'"
I think you meant to do:
docker exec -i <id> /bin/sh < <(echo "echo 'foo'")
which is just the same as:
docker exec -i <id> /bin/sh <<<"echo 'foo'"
@edit There is a cool little trick. The idea is to pipe the script itself except first lines to another subprocess, it's sometimes used by installer scripts:
# output this script except first 4 lines to docker
tail -n+5 "$0" | docker run -i --rm alpine /bin/sh -x
exit # we exit original script
# inside docker now
$ bash -x ./script.sh
+ tail -n+5 ./script.sh
+ docker run -i --rm alpine /bin/sh -x
+ echo abc
+ ls /
In a similar fashion you could use
sed or another parsing tool to extract the only the relevant part between some marks for example.
How can i execute 2 seperate commands in a Dockerfile?
Two options are available to do this.
Use a shell and
&& to execute two commands.
FROM debian:stretch-slim as builder
CMD touch test.txt && ls
Put all commands you want to execute in executable script
entrypoint.sh and run that script in
FROM debian:stretch-slim as builder
COPY entrypoint.sh /entrypoint.sh
Please note, that the commands will by default be executed sequentially so the second command will only be executed after the first. If your first process does never terminate, the second one will never start. Use
& to execute commands in the background. For more information on how to run commands in parallel or sequentially please see this thread.
how to use multiple command in docker-compose cli
To execute multiple commands use bash.
docker exec <container_name> bash "-c" "cd / && ls "
Execute multiple commands from shell to docker container
This is actually possibla using a file to execute multiple commands. Put your mongo script into a file.
Then you can execute this file with
mongo < myFile.js
In your situation:
docker exec -it mongoDB bash -c 'mongo < myFile.js'
Don't forget to copy this file into your docker container.
You can read more here