bash 如何使用单个命令在 Dockerfile 中输出多行字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/54397706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to output a multiline string in Dockerfile with a single command
提问by E235
I want to output the following text in a Dockerfile:
我想在 Dockerfile 中输出以下文本:
*****first row *****
*****second row *****
One way is to do it like that:
一种方法是这样做:
cat > Dockerfile <<EOF
FROM alpine:latest
RUN echo ' *****first row ***** ' >> /home/myfile
RUN echo ' *****second row ***** ' >> /home/myfile
ENTRYPOINT cat /home/myfile; sh;
WORKDIR /home
EOF
But if I have 100 lines it takes time because it runs each command separately and make it as a layer.
但是,如果我有 100 行,则需要时间,因为它分别运行每个命令并将其作为一个层。
Other way is like that:
另一种方式是这样的:
FROM alpine:latest
RUN printf ' *****first row ***** \n *****second row ***** \n' >> /home/myfile
ENTRYPOINT cat /home/myfile; sh;
WORKDIR /home
but I don't like it because it make it less readable, especially when you have 100 lines.
但我不喜欢它,因为它降低了可读性,尤其是当你有 100 行时。
I wonder is there a way to do something like that:
我想知道有没有办法做这样的事情:
FROM alpine:latest
RUN echo ' *****first row *****
*****second row ***** ' >> /home/myfile
ENTRYPOINT cat /home/myfile; sh;
WORKDIR /home
Or is there a way to use the ARG
command to do it ?
或者有没有办法使用ARG
命令来做到这一点?
回答by sirlanceoflompoc
There is another question similar to this with a solution: How to write commands with multiple lines in Dockerfile while preserving the new lines?
还有一个类似的问题有一个解决方案: 如何在 Dockerfile 中编写多行命令同时保留新行?
The answer to this question is more particular in how to use multiline strings in bash rather than how to use Docker.
这个问题的答案更具体的是如何在bash中使用多行字符串而不是如何使用Docker。
Following this solution you may accomplish what you want to do as shown below:
按照此解决方案,您可以完成您想要执行的操作,如下所示:
RUN echo $' \n\
*****first row ***** \n\
*****second row ***** \n\
*****third row ***** ' >> /home/myfile
More info about this leading dollar sign here: How does the leading dollar sign affect single quotes in Bash?
有关此领先美元符号的更多信息:领先的美元符号 如何影响 Bash 中的单引号?
Note that this syntax relies on the run command using /bin/bash, not /bin/sh.
请注意,此语法依赖于使用 /bin/bash 而不是 /bin/sh 的运行命令。
回答by David Maze
If you have a moderately-sized file, it's usually easier to store it in a separate file and just COPY
it in.
如果您有一个中等大小的文件,通常更容易将其存储在单独的文件中,然后将其单独存储COPY
。
FROM alpine:latest
COPY myfile.txt /
CMD cat /myfile.txt
This extends to ENTRYPOINT
and CMD
commands too. Rather than write a complex shell command (especially as an ENTRYPOINT
), it's usually easier to write a separate shell script. If it was important for your application to print the contents of that file before running the main thing the container does, you could write an entrypoint script like
这也扩展到ENTRYPOINT
和CMD
命令。与编写复杂的 shell 命令(尤其是作为ENTRYPOINT
)相比,编写单独的 shell 脚本通常更容易。如果您的应用程序在运行容器所做的主要事情之前打印该文件的内容很重要,您可以编写一个入口点脚本,如
#!/bin/sh
cat /myfile.txt
exec "$@"
and then the Dockerfile
然后是 Dockerfile
FROM alpine:latest
COPY myfile.txt entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["???"]
This also gives you a place to modify the file at runtime (say, using sed(1)) before running the main program if its actual contents need to depend on environment variables or other runtime data.
如果文件的实际内容需要依赖于环境变量或其他运行时数据,这也使您可以在运行主程序之前在运行时修改文件(例如,使用sed(1))。