如何在Docker中使用redirect

将Docker输出保存到主机

docker run centos cat /etc/hosts > asdf 

“asdf”保存在我的主机Linux中。

将Docker输出保存到容器

 docker run centos sh -c 'cat /etc/hosts > /tmp/asdf ' docker run centos cat /tmp/asdf cat: /tmp/asdf: No such file or directory 

它不工作,我怎么能猫新的文件?

在容器中使用“<”

 docker run centos sh -c 'cat < /etc/hosts' 127.0.0.1 localhost 

用“<”读取文件

 docker run centos cat < /etc/hosts 

什么都没发生。

我怎样才能在容器中获取主机文件?

首先,您必须了解shellparsing每个命令的方式,这些命令指示Docker运行的是什么,以及Docker完全执行的是什么。 我会依次查看每个案例。

将Docker输出保存到主机

 docker run centos cat /etc/hosts > asdf 

首先你的shell会parsing这一行,并find>redirect,然后是一个文件名。 它将首先打开(或覆盖)一个名为asdf的文件。 然后它会运行这个命令:

 docker run centos cat /etc/hosts 

并将该命令的标准输出引导到已打开的文件asdf 。 Docker从来不知道asdf任何内容,只是写给标准输出。 shell处理文件创build。

将Docker输出保存到容器

 docker run centos sh -c 'cat /etc/hosts > /tmp/asdf ' 

在这里,你有一个引用string内的redirect,它作为parameter passing给docker命令。 到现在为止还挺好。 Docker将创build一个新的容器(我将其称为“A”),将其放在centos映像上,然后在容器 “A”中执行:

 sh -c 'cat /etc/hosts > /tmp/asdf ' 

因为这发生在容器“A”内,所创build的文件是在容器内部创build的,而不是在外部主机系统上创build的。

接下来,这是运行:

 docker run centos cat /tmp/asdf 

这里没有redirect,所以cat命令按原样传递给Docker。 在这里你再次使用docker run 。 Docker将在这里创build另一个新的容器,我将其称为“B”。 它不是在容器“A”中运行这个命令,这是一个完全不同的容器(尽pipe它们都基于centos映像)。

该文件是在容器“A”中创build的,但是现在您正尝试在容器“B”中读取它。 由于容器是完全独立的,并且每个都有自己的文件系统,因此文件不在容器“B”中。 因此,你得到的错误。

 cat: /tmp/asdf: No such file or directory 

在容器中使用“<”

 docker run centos sh -c 'cat < /etc/hosts' 

再一次, <redirect在引号内,并作为parameter passing。 这一切都发生在容器内部。 基于centos创build一个新的容器“C”, cat命令读取并打印文件。

 127.0.0.1 localhost 

用“<”读取文件

 docker run centos cat < /etc/hosts 

这里< redirect没有被引用,所以你的shell在传递给Docker之前解释它。 真正运行的是这样的:

 docker run centos cat 

Docker将根据centos映像创build一个新的容器“D”,并在该容器内运行cat命令。 由于cat没有任何关系,它只是退出,你的容器也是如此。

同时,redirect已经挂钩了标准input来stream式处理主机的/etc/hosts文件的内容。 但是,你没有使用交互模式( -i ),所以容器不听标准input; 它被忽略了。

如果你使用-i ,那么你的主要主机的/etc/hosts文件将被打印。

如何做你正在做的事情

最初你试图将一个文件redirect到容器内的另一个文件,然后将其捕获。 不幸的是,你所做的是在一个容器中创build一个文件的副本,然后尝试在不同的容器中读取它(它不存在的地方)。 有几种方法可以实现这一点。

你可以在同一个docker run运行这两个命令:

 docker run centos sh -c 'cat /etc/hosts > /tmp/asdf; cat /tmp/asdf' 

如果你有一个已经在运行的容器,你可以使用docker exec

 docker exec <container-id> 'cat /etc/hosts > /tmp/asdf' docker exec <container-id> 'cat /tmp/asdf' 

我怎样才能猫容器中的主机文件?

如果该容器立即退出,则需要将停止的容器提交到新的映像中,然后:

 docker run new_image cat /tmp/asdf