I am using Docker to write a file on the fly and run it. The command looks like this so far (just to test the idea first):
docker run dockerfile/python cat <<EOF >hi.txt && tail hi.txt
> hi there
> EOF
For some reason this does not echo anything.
If I run this command without a HEREDOC then it does output the result. For example the following works:
docker run dockerfile/python cat > hi.txt && ls
hi.txt
How do I output the result of a multi line run command/HEREDOC.
I'm curious, what shell are you using so that the second command works? Because in bash the hi.txt
is created on the host and so is the ls
.
bash-3.2$ docker run --rm dockerfile/python cat > hi.txt && ls
Applications Desktop Documents Downloads Dropbox Library Movies Music Pictures Public VirtualBox VMs hi.txt projects
To achieve that, I'd have to use:
docker run --rm dockerfile/python bash -c 'cat > hi.txt && ls'
IMO, the simplest way to test stuff is to just use a container as a sandbox:
docker run -it dockerfile/python bash
And then just do stuff in that container's shell. Once I got things running well, I backport what I've done in a Dockerfile.
I was fiddling with crossbuild* and was wondering about how to use here documents to pipe commands to a Docker container. Here's the solution.
$ docker run --rm --interactive --volume $(pwd):/workdir --env CROSS_TRIPLE=x86_64-apple-darwin multiarch/crossbuild /bin/bash -s <<EOF
mkdir build && cd build
cmake ..
make
EOF
Quick rundown of what's happening.
--rm
tells Docker to remove the container when it finished execution, otherwise it would show up in the output docker ps -a
(not mandatory to use of course)
--interactive
, -i
is needed, otherwise /bin/bash
would not run in an interactive environment and would not accept the here document from stdin as its input
- about the
-s
flag passed to /bin/bash
If the -s option is present, or if no arguments remain after option
processing, then commands are read from the standard input.
--volume $(pwd):/workdir
, just -v
will mount the current working directory on the host to /workdir
in the container
--env CROSS_TRIPLE=x86_64-apple-darwin
, or simple -e
tells the crossbuild
container about the target platform and architecture (the container's entry point is /usr/bin/crossbuild
, which is a shell script and based on the environment variable it's symlink the right toolchain components to the right places for the cross compilation to work)
multiarch/crossbuild
the name of the Docker container to run (available in Docker Hub)
The commands can be fed to Docker like this as well.
$ cat a.sh
mkdir build && cd build
cmake ..
make
$ docker run --rm -i -v $(pwd):/workdir -e CROSS_TRIPLE=x86_64-apple-darwin multiarch/crossbuild /bin/bash -s < a.sh
Hoped this helps.
Update
Actually it seems you don't even need to use /bin/bash -s
, it can be ommited, at least for the crossbuild
container, YMMV.
*Linux based container used to produce multi-arch binaries: Linux, Windows and OS X, very cool.