问题
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.
回答1:
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.
回答2:
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.
--rmtells Docker to remove the container when it finished execution, otherwise it would show up in the outputdocker ps -a(not mandatory to use of course)--interactive,-iis needed, otherwise/bin/bashwould not run in an interactive environment and would not accept the here document from stdin as its input- about the
-sflag passed to/bin/bashIf 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-vwill mount the current working directory on the host to/workdirin the container--env CROSS_TRIPLE=x86_64-apple-darwin, or simple-etells thecrossbuildcontainer 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/crossbuildthe 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.
来源:https://stackoverflow.com/questions/27370178/running-a-longer-command-from-docker