如何在需要tty的Docker构build期间运行命令?

我有一些脚本我需要在Docker构build期间运行,这需要一个tty(Docker在构build期间不提供)。 脚本使用read命令。 一个tty,我可以做一些事情(echo yes; echo no) | myscript.sh (echo yes; echo no) | myscript.sh

没有它我得到奇怪的错误,我不完全明白。 那么有没有什么办法可以在构build过程中使用这个脚本(假设它不是我的修改?)

编辑:这是一个更确定的错误的例子:

 FROM ubuntu:14.04 RUN echo yes | read 

失败与:

 Step 0 : FROM ubuntu:14.04 ---> 826544226fdc Step 1 : RUN echo yes | read ---> Running in 4d49fd03b38b /bin/sh: 1: read: arg count The command '/bin/sh -c echo yes | read' returned a non-zero code: 2 

Solutions Collecting From Web of "如何在需要tty的Docker构build期间运行命令?"

您不需要用于将数据馈送到脚本的tty。 只是做一些像(echo yes; echo no) | myscript.sh (echo yes; echo no) | myscript.sh正如你所建议的那样。 也请确保您先复制您的文件,然后再尝试执行它。 像COPY myscript.sh myscript.sh

Dockerfile参考中RUN <command>

shell形式,命令运行在一个shell中,默认情况下是Linux上的/ bin / sh -c或Windows上的cmd / S / C

让我们看看究竟是/bin/sh在Ubuntu中:14.04:

 $ docker run -it --rm ubuntu:14.04 bash root@7bdcaf403396:/# ls -n /bin/sh lrwxrwxrwx 1 0 0 4 Feb 19 2014 /bin/sh -> dash 

/ bin / sh是dash的符号链接,请参阅dash read函数:

 $ man dash ... read [-p prompt] [-r] variable [...] The prompt is printed if the -p option is specified and the standard input is a terminal. Then a line is read from the standard input. The trailing newline is deleted from the line and the line is split as described in the section on word splitting above, and the pieces are assigned to the variables in order. At least one variable must be specified. If there are more pieces than variables, the remaining pieces (along with the characters in IFS that separated them) are assigned to the last variable. If there are more variables than pieces, the remaining variables are assigned the null string. The read builtin will indicate success unless EOF is encountered on input, in which case failure is returned. By default, unless the -r option is specified, the backslash ``\'' acts as an escape character, causing the following character to be treated literally. If a backslash is followed by a newline, the backslash and the newline will be deleted. ... 

dash read功能:

至少必须指定一个变量。

让我们看看bashread函数:

 $ man bash ... read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name...] If no names are supplied, the line read is assigned to the variable REPLY. The return code is zero, unless end-of-file is encountered, read times out (in which case the return code is greater than 128), or an invalid file descriptor is supplied as the argument to -u. ... 

所以我猜你的脚本myscript.sh是以#!/bin/bash或别的东西而不是/bin/sh开头的。

另外,你可以像下面这样改变你的Dockerfile

 FROM ubuntu:14.04 RUN echo yes | read ENV_NAME 

链接:

很有可能你不需要一个tty。 正如对问题的评论所示,即使是提供的例子,也是一个read命令没有正确调用的情况。 一个tty会把这个构建变成一个交互式的终端过程,这个过程并不能很好地转化成可以从没有终端的工具运行的自动构建。

如果你需要一个tty,那么就有一个C库调用openpty ,你可以在派生一个包含一个伪tty的进程时使用它。 你也许可以用expect的工具来解决你的问题,但是我不记得它是否创建了一个ptty。 或者,如果您的应用程序无法自动构建,则可以手动在正在运行的容器中执行这些步骤,然后docker commit所产生的容器以创建图像。

我建议对任何这些,并制定程序来建立你的应用程序,并以非交互式的方式进行安装。 取决于应用程序,修改安装程序本身可能更容易。