我需要在Docker构建期间运行一些需要tty的脚本(Docker在构建期间不提供)。在脚本下,脚本使用read
命令。 使用 tty,我可以执行(echo yes; echo no) | myscript.sh
之类的内容。
编辑:这是错误的更明确的例子:
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
答案 0 :(得分:0)
您不需要tty来将数据提供给脚本。只是像你建议的那样做(echo yes; echo no) | myscript.sh
之类的事情。另外,请确保在尝试执行文件之前先复制文件。像COPY myscript.sh myscript.sh
答案 1 :(得分:0)
RUN <command>
参考中的 Dockerfile
:
shell表单,该命令在shell中运行,默认情况下是Linux上的/ bin / sh -c或Windows上的cmd / S / C
让我们看看ubuntu中的/bin/sh
究竟是什么: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
的符号链接,请参阅read
中的dash
函数:
$ 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.
...
read
中的 dash
功能:
必须至少指定一个变量。
让我们在read
中看到bash
函数:
$ 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
<强>链接:强>
答案 2 :(得分:-1)
很可能你不需要tty。正如对问题的评论所示,即使提供的示例也是未正确调用read
命令的情况。 tty会将构建转换为交互式终端进程,这不能很好地转换为可以从没有终端的工具运行的自动构建。
如果你需要tty,那么你可以在分配包含伪tty的进程时使用openpty
的C库调用。您可以使用像expect
这样的工具来解决您的问题,但是它已经很久了,我不记得它是否创建了一个ptty。或者,如果您的应用程序无法自动构建,您可以在正在运行的容器中手动执行这些步骤,然后docker commit
生成的容器以生成图像。
我建议不要使用其中任何一个,并制定程序来构建应用程序并以非交互方式安装它。根据应用程序的不同,修改安装程序本身可能更容易。