7

假设我将 docker 容器作为守护进程运行:

docker run -d foo

有没有办法写入该容器的标准输入?就像是:

docker exec -i foo echo 'hi'

上次我检查-i和标志在与命令-d一起使用时是互斥的。docker run

4

2 回答 2

8

根据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.exesave因为exitstdin.

于 2020-06-01T22:33:39.097 回答
5

原则上你可以docker attachCTRL+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 中运行它会容易得多。

于 2020-01-21T10:44:07.657 回答