Linux 如何向容器发送命令以在不运行容器的情况下更改文件?
我有一个容器Linux 如何向容器发送命令以在不运行容器的情况下更改文件?,linux,bash,docker,shell,containers,Linux,Bash,Docker,Shell,Containers,我有一个容器Postgres,它在Dockerfile中启动一个docker entrypoint.sh,在这个shell文件中有一个命令,我想使用这个命令删除它: sed -i 's/exec "$@"//g' docker-entrypoint.sh docker run -v $(pwd):/docker-entrypoint-initdb.d -e POSTGRES_PASSWORD=password \ --entrypoint="docker
Postgres
,它在Dockerfile中启动一个docker entrypoint.sh
,在这个shell文件中有一个命令,我想使用这个命令删除它:
sed -i 's/exec "$@"//g' docker-entrypoint.sh
docker run -v $(pwd):/docker-entrypoint-initdb.d -e POSTGRES_PASSWORD=password \
--entrypoint="docker-entrypoint-initdb.d/docker-entrypoint-custom.sh" postgres postgres
目标是能够使用修改后的docker-entrypoint.sh运行容器(不使用exec“@”)
如何在之前启动该命令的情况下运行容器?
我使用了另一种方法,在该方法中,我使用另一个不带“exec”@“的shell文件覆盖docker-entrypoint.sh,然后使用以下命令装载它以运行我的容器:
sed -i 's/exec "$@"//g' docker-entrypoint.sh
docker run -v $(pwd):/docker-entrypoint-initdb.d -e POSTGRES_PASSWORD=password \
--entrypoint="docker-entrypoint-initdb.d/docker-entrypoint-custom.sh" postgres postgres
我确信有一种更好的方法,在bash中运行命令,然后运行自己的命令
我尝试过类似的方法,但不起作用:
docker run --rm -v $PWD:/docker-entrypoint-initdb.d -e POSTGRES_PASSWORD=password --entrypoint=/bin/bash postgres sed -i 's/exec "$@"//g' docker-entrypoint.sh && postgres docker-entrypoint.sh
我使用了另一种方法,使用另一个不带“exec”@“的shell文件覆盖docker-entrypoint.sh
好的,你正在挂载一个完整的目录,你有一个入口点的副本。只需挂载一个文件,并在文件中进行修改
# docker-entrypoint-custom.sh
#!/bin/sh
# do the modification
sed -i 's/exec "$@"//g' /docker-entrypoint.sh
# Just run it
/docker-entrypoint.sh "$@"
另一种方法是使用修改的入口点构建另一个容器
# Dockefile....
FROM postgres
RUN sed -i 's/exec "$@"//g' /docker-entrypoint.sh
我使用了另一种方法,使用另一个不带“exec”@“的shell文件覆盖docker-entrypoint.sh
好的,你正在挂载一个完整的目录,你有一个入口点的副本。只需挂载一个文件,并在文件中进行修改
# docker-entrypoint-custom.sh
#!/bin/sh
# do the modification
sed -i 's/exec "$@"//g' /docker-entrypoint.sh
# Just run it
/docker-entrypoint.sh "$@"
另一种方法是使用修改的入口点构建另一个容器
# Dockefile....
FROM postgres
RUN sed -i 's/exec "$@"//g' /docker-entrypoint.sh
postgres
图像的默认操作是运行postgres
。如果您想让它运行其他命令,只需将该命令放在docker run
命令的末尾即可。不要担心编辑入口点脚本
出于调试的目的,一件非常典型的事情是启动一个交互式shell,而不是正常的服务器进程;然后,您可以查看创建的文件系统,看看发生了什么
docker run --rm -it \
-v $PWD:/docker-entrypoint-initdb.d \
-e POSTGRES_PASSWORD=password \
postgres \
/bin/bash
这里到底发生了什么?如果您查看,您会注意到它同时包含一个入口点和一个CMD
:
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["postgres"]
当你两样东西都有的时候。exec“$@”
行将入口点脚本替换为另一个由位置参数组成的命令;也就是说,它将docker entrypoint.sh
替换为postgres
。在命令行中重写CMD
很容易,正如我在上面所做的那样,但是替换ENTRYPOINT
更为棘手
这就形成了一种通用模式,即使用ENTRYPOINT
进行首次初始化,然后使用exec“$@”
运行CMD
#/垃圾箱/垃圾箱
#我是docker-entrypoint.sh
#以Dockerfile的形式调用我(必须使用JSON数组语法)
#入口点[“/path/to/ENTRYPOINT.sh”]
#执行启动时初始化,如创建数据库或
#为主进程设置环境变量
...
#然后启动CMD
执行官“$@”
postgres图像的默认操作是运行postgres
。如果您想让它运行其他命令,只需将该命令放在docker run
命令的末尾即可。不要担心编辑入口点脚本
出于调试的目的,一件非常典型的事情是启动一个交互式shell,而不是正常的服务器进程;然后,您可以查看创建的文件系统,看看发生了什么
docker run --rm -it \
-v $PWD:/docker-entrypoint-initdb.d \
-e POSTGRES_PASSWORD=password \
postgres \
/bin/bash
这里到底发生了什么?如果您查看,您会注意到它同时包含一个入口点和一个CMD
:
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["postgres"]
当你两样东西都有的时候。exec“$@”
行将入口点脚本替换为另一个由位置参数组成的命令;也就是说,它将docker entrypoint.sh
替换为postgres
。在命令行中重写CMD
很容易,正如我在上面所做的那样,但是替换ENTRYPOINT
更为棘手
这就形成了一种通用模式,即使用ENTRYPOINT
进行首次初始化,然后使用exec“$@”
运行CMD
#/垃圾箱/垃圾箱
#我是docker-entrypoint.sh
#以Dockerfile的形式调用我(必须使用JSON数组语法)
#入口点[“/path/to/ENTRYPOINT.sh”]
#执行启动时初始化,如创建数据库或
#为主进程设置环境变量
...
#然后启动CMD
执行官“$@”
您当前使用的方法是iMO此处选项中最好的。您将单引号与sed
命令一起使用,并在其中使用$@
变量。注意,单引号内的任何变量都不会被插值。请使用双引号。@Pexec“$@”
可能是OP想要替换的,也就是说,按原样,不需要任何替换。您当前使用的方法是iMO这里的选项中最好的。您使用带有sed
命令的单引号,并在其中使用$@
变量。注意,单引号内的任何变量都不会被插值。请使用双引号。@Pexec“$@”
可能是OP想要替换的东西,即原样,没有任何替换。这太干净了!谢谢你,它成功了!这太干净了!谢谢你,它成功了!谢谢你的解释@David,但我的目标是从我的主shell文件中删除“exec”@!一旦你有了它,你会做什么?如果您只想让容器在卷中设置初始数据库并运行初始化脚本,可以将命令设置为类似于/bin/true
,其最终效果与删除行相同。目标是使用此容器运行架构测试/bin/true会取代/bin/sh吗?(我不知道)如果你docker运行。。。postgres/bin/true
它将启动entrypoint脚本。当它到达e