假设我将 docker 容器作为守护进程运行:
docker run -d foo
有没有办法写入该容器的标准输入?就像是:
docker exec -i foo echo 'hi'
上次我检查-i
和标志在与命令-d
一起使用时是互斥的。docker run
假设我将 docker 容器作为守护进程运行:
docker run -d foo
有没有办法写入该容器的标准输入?就像是:
docker exec -i foo echo 'hi'
上次我检查-i
和标志在与命令-d
一起使用时是互斥的。docker run
根据ServerFault 上的另一个答案,您可以使用socat
管道输入到 docker 容器,如下所示:
echo 'hi' | socat EXEC:"docker attach container0",pty STDIN
请注意,该echo
命令在输出末尾包含换行符,因此上面的行实际上发送hi\n
. echo -n
如果您不想要换行符,请使用。
让我们看看大卫回答中的示例脚本是什么样子的:
# Create a new empty directory
mkdir x
# Run a container, in the background, that copies its stdin
# to a file in that directory
docker run -itd --rm -v $PWD/x:/x --name cattainer busybox sh -c 'cat >/x/y'
# Send some strings in
echo 'hi' | socat EXEC:"docker attach cattainer",pty STDIN
echo 'still there?' | socat EXEC:"docker attach cattainer",pty STDIN
# Stop container (cleans up itself because of --rm)
docker stop cattainer
# See what we got out
cat x/y
# should output:
# hi
# still there?
您也可以将其包装在 shell 函数中:
docker_send() {
container="$1"; shift
echo "$@" | socat EXEC:"docker attach $container",pty STDIN
}
docker_send cattainer "Hello cat!"
docker_send cattainer -n "No newline here:" # flag -n is passed to echo
琐事:我实际上是使用这种方法来控制在 docker 容器中运行的 Terraria 服务器TerrariaServer.exe
,save
因为exit
在stdin
.
原则上你可以docker attach
。 CTRL+C将停止容器(通过向进程发送 SIGINT);CTRL+ P, CTRL+Q将与它分离并让它继续运行(如果你用 启动了容器docker run -it
)。
这里的一个技巧是docker attach
期望在某种终端中运行;你可以做一些类似运行它script
来满足这个要求。这是一个例子:
# Create a new empty directory
mkdir x
# Run a container, in the background, that copies its stdin
# to a file in that directory
docker run -itd -v $PWD/x:/x --name cat busybox sh -c 'cat >/x/y'
# Send a string in
echo foo | script -q /dev/null docker attach cat
# Note, EOF here stops the container, probably because /bin/cat
# exits normally
# Clean up
docker rm cat
# See what we got out
cat x/y
在实践中,如果程序通信的主要方式是通过标准输入和标准输出上的文本,那么 Docker 并不是一个很好的打包机制。在 Docker Compose 或 Kubernetes 等更高级别的环境中,以这种方式发送内容变得越来越困难,并且经常假设容器可以完全自主运行。只是调用程序很快就会变得复杂(正如这个问题所暗示的那样)。如果您有类似 create-react-app 设置工具之类的东西,它会询问一堆交互式问题,然后将内容写入主机文件系统,那么直接在主机上而不是在 Docker 中运行它会容易得多。