且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Docker build中运行需要tty的命令?

更新时间:2023-01-15 22:40:22

code>运行< 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 - >破折号

/ bin / sh是一个符号链接 dash ,请参阅 dash 中的读取函数:

  $ man dash 
...
读取[-p提示] [-r]变量[...]
如果-p选项被指定,标准输入是终端。然后从标准输入读取一行
。尾随的换行符从行中删除,行被拆分为
,在上面的单词分割部分中描述,并且这些段按顺序分配给变量。
必须至少指定一个变量。如果存在比变量多的部分,则剩下的部分
(与IFS中的字符一起分隔)分配给最后一个变量。如果
多于变量,剩余的变量将被分配空字符串。读内置将
表示成功,除非在输入时遇到EOF,否则返回失败。

默认情况下,除非指定了-r选项,否则反斜杠\用作转义字符,导致
将字面处理以下字符。如果反斜杠后面是换行符,则反斜杠
和换行符将被删除。
...

读取 dash 中的功能:


必须至少指定一个变量。 >

让我们看看 bash中的函数

  $ man bash 
...
读[-ers] [-a aname ] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
如果没有名字提供,行读取被分配给变量REPLY。返回代码为零,
,除非遇到文件结束,读取超时(在这种情况下返回码大于
128),或者提供无效的文件描述符作为参数-u。
...

所以我猜你的脚本 myscript.sh 开始于#!/ bin / bash 或其他东西,但不是 / bin / sh



另外,您可以更改 Dockerfile ,如下所示:

  FROM ubuntu:14.04 
RUN echo yes |阅读ENV_NAME

链接




I have some script I need to run during a Docker build which requires a tty (which Docker does not provide during a build). Under the hood the script uses the read command. With a tty, I can do things like (echo yes; echo no) | myscript.sh.

Without it I get strange errors I don't completely understand. So is there any way to use this script during the build (given that its not mine to modify?)

EDIT: Here's a more definite example of the error:

FROM ubuntu:14.04
RUN echo yes | read

which fails with:

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

RUN <command> in Dockerfile reference:

shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows

let's see what exactly /bin/sh is in 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 is a symbolic link of dash, see read function in 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 function in dash:

At least one variable must be specified.

let's see read function in 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.
...

So I guess your script myscript.sh is start with #!/bin/bash or something else but not /bin/sh.

Also, you can change your Dockerfile like below:

FROM ubuntu:14.04
RUN echo yes | read ENV_NAME

Links: