我有一些脚本我需要在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
您不需要用于将数据馈送到脚本的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
功能:
至少必须指定一个变量。
让我们看看bash
的read
函数:
$ 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
所产生的容器以创建图像。
我建议对任何这些,并制定程序来建立你的应用程序,并以非交互式的方式进行安装。 取决于应用程序,修改安装程序本身可能更容易。