如何通过Docker访问C++程序生成的输出文件?
问题分析与解决方案
首先咱们得搞清楚问题出在哪:你的程序把输出文件result.md写到了容器的当前工作目录(也就是Dockerfile里设置的/repo),但你运行容器时挂载的是/home/user/tmp/:/repo/dir——这意味着只有容器里的/repo/dir目录和宿主的/home/user/tmp/是同步的,而/repo根目录里的文件根本没和宿主共享,所以你在宿主的tmp目录里找不到输出文件。
下面给你几种可行的解决办法,按需选择:
方法1:调整挂载路径,直接共享程序工作目录
这是最直接的方式,把宿主的/home/user/tmp/直接挂载到容器的/repo目录(也就是程序的工作目录),这样程序生成的输出文件会直接同步到宿主的tmp目录。修改后的运行命令如下:
docker run -v /home/user/tmp/:/repo image file1 file2
这里注意输入文件的参数:因为现在宿主的/home/user/tmp/file1直接对应容器里的/repo/file1,所以命令里直接传file1和file2就行,不用再加dir/前缀了。
方法2:从已运行的容器中拷贝输出文件
如果已经执行了原命令,不想重新运行程序,可以用docker cp命令把容器里的result.md拷贝到宿主机器:
- 先找到容器的ID(哪怕容器已经停止运行也没关系):
docker ps -a - 执行拷贝命令,把
<容器ID>替换成你实际的容器ID:docker cp <容器ID>:/repo/result.md /home/user/tmp/
方法3:修改程序或Dockerfile,指定输出到挂载目录
如果你不想调整挂载路径,也可以让程序把输出写到容器里的/repo/dir目录(也就是和宿主同步的目录):
- 直接修改C++代码,把输出文件路径改成
dir/result.md(或者让程序接受一个输出路径参数,运行时指定); - 或者修改Dockerfile,把工作目录改成
/repo/dir,但这样需要调整COPY和RUN make的路径,确保编译过程能正常执行,比如:
不过这种方式需要确保makefile的编译路径没问题,相对来说不如方法1简便。FROM gcc:7.2.0 ENV MYP /repo WORKDIR ${MYP}/dir COPY . ${MYP} RUN cd ${MYP} && make ENTRYPOINT ["./program"] CMD ["file1", "file2"]
关于Docker卷机制的疑问
你完全可以通过Docker的绑定挂载(也就是你现在用的-v参数)直接获取输出文件——本质上你已经在使用卷机制了,只是之前挂载的目录不对。只要把宿主目录和容器里程序生成输出的目录(也就是/repo)绑定,就能实现实时同步,不需要额外的操作。
内容的提问来源于stack exchange,提问作者elcortegano
相关产品推荐
相关产品推荐

