shell 到 Docker 容器后如何编辑文件?

Posted

技术标签:

【中文标题】shell 到 Docker 容器后如何编辑文件?【英文标题】:How do I edit a file after I shell to a Docker container? 【发布时间】:2015-08-31 10:12:48 【问题描述】:

我成功地使用了一个 Docker 容器:

docker exec -i -t 69f1711a205e bash

现在我需要编辑文件,但里面没有任何编辑器:

root@69f1711a205e:/# nano
bash: nano: command not found
root@69f1711a205e:/# pico
bash: pico: command not found
root@69f1711a205e:/# vi
bash: vi: command not found
root@69f1711a205e:/# vim
bash: vim: command not found
root@69f1711a205e:/# emacs
bash: emacs: command not found
root@69f1711a205e:/#

如何编辑文件?

【问题讨论】:

@Opal 我使用 confluent/postgres-bw:0.1 @Opal apt-get install vim 有效。谢谢! 那么为什么不创建Dockerfile 并包含 apt-get install 命令并生成您自己的容器呢? Docker 容器就是这样设计的,而不是你的方式。 docker 应该至少安装在测试编辑器上,至少默认安装 vim 运行以下命令在容器中安装“nano” $ apt-get update $ apt-get install nano 【参考方案1】:

与 cmets 一样,没有设置默认编辑器 - 奇怪 - $EDITOR 环境变量为空。您可以使用以下命令登录容器:

docker exec -it <container> bash

然后运行:

apt-get update
apt-get install vim

或者使用以下 Dockerfile:

FROM  confluent/postgres-bw:0.1

RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "vim"]

Docker 镜像在交付时已进行了最低限度的修整 - 因此在交付的容器中未安装任何编辑器。这就是为什么需要手动安装它的原因。

编辑

我也鼓励你阅读我的post 关于这个话题。

【讨论】:

你需要的是挂载一个卷:docs.docker.com/userguide/dockervolumes 我需要以 root 身份登录才能完成此操作docker exec -u 0 -it container_name bash 与 docker 一样,最好安装 vim-tiny,可能。 也许您可以考虑不在您附加的每个容器中安装编辑器,而是在 docker 主机上安装一次。正如其他评论员所提到的,您可以挂载卷,因此您可以编辑将要挂载的文件,或者导航到容器数据本身并编辑 /var/lib/docker/ 中的文件 我只是想在容器中将一个配置从 true 更改为 false。 apt-get 由于容器内的权限问题而无法正常工作,所以我尝试了 sed -i 's/texttobechanged/textwanted/g' filename 。它对我有用。【参考方案2】:

如果您不想添加编辑器只是为了进行一些小的更改(例如,更改 Tomcat 配置),您可以使用:

docker cp <container>:/path/to/file.ext .

它将它复制到您的本地计算机(到您的当前目录)。然后使用你喜欢的编辑器在本地编辑文件,然后做一个

docker cp file.ext <container>:/path/to/file.ext

替换旧文件。

【讨论】:

@Igor 这实际上应该是公认的解决方案,因为它是在不向容器添加额外包的情况下执行此操作的正确方法,而添加包应该是次要解决方案。 对于Windows平台,可以使用,例如:docker cp &lt;container&gt;:C:\inetpub\wwwroot\Web.config .docker cp Web.config &lt;container&gt;:C:\inetpub\wwwroot\Web.config 测试目的的好方法!我不建议在生产中这样做。 您对生产有什么建议?人们是否应该在生产环境中以交互方式编辑容器中的文件? 值得注意的是,此方法更改了文件所有权。之后可以通过以 root (docker exec -u 0 -it mycontainer bash) 身份进入容器然后运行chown 命令将其更改回来,但有点繁琐。【参考方案3】:

如果已安装cat,则可以使用它,如果它不是裸/原始容器,则很可能是这种情况。它可以在紧要关头工作,并且在本地复制+粘贴到适当的编辑器时也可以。

cat > file
# 1. type in your content
# 2. leave a newline at end of file
# 3. ctrl-c / (better: ctrl-d)
cat file

cat 将在收到换行符时输出每一行。确保为最后一行添加换行符。 ctrl-c 发送一个SIGINT 让 cat 优雅地退出。从 cmets 中您可以看到,您还可以按 ctrl-d 来表示文件结束(“不再有输入”)。

另一个选项类似于infilter,它使用一些 ptrace 魔法将进程注入容器命名空间:https://github.com/yadutaf/infilter

【讨论】:

如果存在灌输权限问题,这将非常有用! ctrl+D 优于 ctrl+Cctrl+D 发送一个EOF。您不需要在末尾添加额外的换行符。使用ctrl+C,如果忘记添加换行符,会丢失最后一行! @wisbucky 不错!甚至更好。不过可能需要按 ctrl-d 两次。 也可以 cat >> 文件追加而不是删除之前的内容。【参考方案4】:

为了让您的 Docker 镜像更小,请不要安装不必要的编辑器。您可以通过 SSH 从 Docker 主机编辑文件到容器:

vim scp://remoteuser@containerip//path/to/document

【讨论】:

谢谢。我想留下这个链接,它更好地解释了vim scp://vim.wikia。另外,要获取容器的 IP 地址,可以使用 sudo docker inspect &lt;container_id&gt; | grep "IPAddress" 只是想知道,我到底是使用“remoteuser”还是“docker”?我试过:vim scp://docker@172.17.0.17//data/gitea/conf/app.inivim scp://remoteuser@172.17.0.17//data/gitea/conf/app.ini,他们都只是创建一个新的空白文件。 @J.ScottElblein 这需要首先在您的 docker 容器上配置 ssh。见blog.softwaremill.com/…。但是您通常不想在容器中安装 ssh【参考方案5】:

对于常见的编辑操作,我更喜欢安装 vi (vim-tiny),它只使用 1491 kBnano,它使用 1707 kB

另一方面,vim 使用 28.9 MB

我们必须记住,为了让apt-get install 工作,我们必须第一次执行update,所以:

apt-get update
apt-get install vim-tiny

要在CLI中启动编辑器,我们需要输入vi

【讨论】:

对我来说这是更简单、更快捷的解决方案,上述解决方案的优点是不下载应用程序,但这是更简单的解决方案。【参考方案6】:

您可以使用

打开现有文件
cat filename.extension

并复制剪贴板上的所有现有文本。

然后用

删除旧文件
rm filename.extension

或用

重命名旧文件
mv old-filename.extension new-filename.extension

创建新文件
cat > new-file.extension

然后将复制的所有文本粘贴到剪贴板上,按Enter 并按ctrl+z 退出并保存。瞧,无需安装任何类型的编辑器。

【讨论】:

【参考方案7】:

有时你必须先用root运行容器:

docker exec -ti --user root <container-id> /bin/bash

然后在容器中,安装 Vim 或其他东西:

apt-get install vim

【讨论】:

这给出了“权限被拒绝”【参考方案8】:

如果安装了cat,您可以使用&gt; 字符。 这是操作:

cat > file_to_edit
#1 Write or Paste you text
#2 don't forget to leave a blank line at the end of file
#3 Ctrl + C to apply configuration

现在你可以用命令看到结果了

cat file

【讨论】:

【参考方案9】:

我使用“docker run”(而不是“docker exec”),并且我处于无法安装编辑器的受限区域。但我在 Docker 主机上有一个编辑器。

我的解决方法是:将 Docker 主机中的卷绑定到容器(https://docs.docker.com/engine/reference/run/#/volume-shared-filesystems),并在容器外编辑文件。它看起来像这样:

docker run -v /outside/dir:/container/dir

这主要是为了实验,后来我会在构建图像时更改文件。

【讨论】:

【参考方案10】:

shell 到 Docker 容器后,只需键入:

apt-get update
apt-get install nano

【讨论】:

【参考方案11】:

您可以在主机上编辑文件,然后快速将其复制到容器中并在容器内运行。这是我复制和运行 Python 文件的单行快捷方式:

docker cp main.py my-container:/data/scripts/ ; docker exec -it my-container python /data/scripts/main.py

【讨论】:

如何回答这个问题? - “我如何编辑文件?”【参考方案12】:

如果您使用 Windows 容器并且想要更改任何文件,您可以在 Powershell 控制台中轻松获取和使用 Vim。

使用 PowerShell 转至 Windows Docker 容器:

docker exec -it &lt;name&gt; powershell

首先安装 Chocolatey 包管理器

Invoke-WebRequest https://chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression;

安装 Vim

choco install vim

刷新环境变量 你可以exit 并返回容器

转到文件位置并将其 Vim vim file.txt

【讨论】:

【参考方案13】:

这有点麻烦,但在紧要关头,您可以使用sedawk 进行小的编辑或删除文本。当然要小心您的正则表达式目标,并注意您的容器上可能是root,并且可能需要重新调整权限。

例如,删除包含匹配正则表达式的文本的整行:

awk '!/targetText/' file.txt > temp && mv temp file.txt

(More)

【讨论】:

【参考方案14】:

查看堆栈溢出问题 sed edit file in place

这将是一个不错的选择,如果:

    修改大文件,无法使用cat

    不允许安装 Vim 或安装时间太长。 我的情况是使用 mysql 5.7 映像,当我想更改 my.cnf 文件时,没有 vimvi,而且 Vim 安装时间太长(中国防火墙)。图中提供了sed,很简单。我的用法是这样的

    sed -i /s/testtobechanged/textwanted/g filename

    使用man sed 或寻找其他教程以获得更复杂的用法。

【讨论】:

【参考方案15】:

如果您只能使用 bin/sh 进入容器(以防 bin/bash 不起作用) 并且apt或apt-get在容器中不起作用,通过在容器内的命令提示符中输入apk来检查是否安装了apk。 如果是,您可以按如下方式安装 nano: apk 添加纳米

然后 nano 将照常工作

【讨论】:

【参考方案16】:

编辑几行的简单方法是:

echo "deb http://deb.debian.org/debian stretch main" > sources.list

【讨论】:

【参考方案17】:

你也可以使用一个特殊的容器,它只包含你需要的命令:Vim。我选择了python-vim。它假定您要编辑的数据位于使用以下 Dockerfile 构建的数据容器中:

FROM debian:jessie
ENV MY_USER_PASS my_user_pass
RUN groupadd --gid 1001 my_user
RUN useradd -ms /bin/bash --home /home/my_user \
            -p $(echo "print crypt("$MY_USER_PASS:-password", "salt")" | perl) \
            --uid 1001 --gid 1001 my_user
ADD src /home/my_user/src
RUN chown -R my_user:my_user /home/my_user/src
RUN chmod u+x /home/my_user/src
CMD ["true"]

您将能够通过安装一个 Docker 卷 (src_volume) 来编辑您的数据,该卷将由您的数据容器 (src_data) 和 python-vim 容器共享。

docker volume create --name src_volume
docker build -t src_data .
docker run -d -v src_volume:/home/my_user/src --name src_data_1 src_data
docker run --rm -it -v src_volume:/src fedeg/python-vim:latest

这样,您无需更改容器。你只需使用一个特殊的容器来完成这项工作。

【讨论】:

【参考方案18】:

我同意@hkong 的回答应该被接受,因为它避免了向容器添加额外的包。但是,我发现将修改后的文件粘贴到容器后,其中一些往往会限制访问,从而导致 docker daemon 无法启动。在这种情况下,为修改后的文件分配一些权限,然后粘贴到容器中。

【讨论】:

以上是关于shell 到 Docker 容器后如何编辑文件?的主要内容,如果未能解决你的问题,请参考以下文章

Linux之shell脚本实战批量上传docker镜像到华为云容器镜像仓库

在 Docker 容器内编辑文件

如何从主机上的编辑器编辑Docker容器中的文件?

如何进入Docker容器

如何构建Memcached Docker容器

VsCode轻松使用docker容器-Remote Containers