如何从docker中检测bash的全交互式shell?

13

我希望在“docker run”命令中检测是否已向entrypoint脚本传递-ti参数。

使用“docker run --help”命令查看有关-t -i参数的更多信息。

-i, --interactive=false     Keep STDIN open even if not attached
-t, --tty=false             Allocate a pseudo-TTY

我尝试了以下方法,但即使在本地测试(不在docker内)也无法工作,并且始终打印出“Not interactive”。
#!/bin/bash

[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'

1
如果你只是回显 $-,你会得到什么?另外,你正在运行哪个版本的 bash? - Eric Renouf
很奇怪,那应该可以工作。我认为-t会起作用。 - hookenz
1
作为脚本运行(/path/to/scriptbash /path/to/script)的脚本不会以交互模式运行。在您的shell提示符下运行该命令或将其源化(. /path/to/script),它将按您预期的方式工作。 - Etan Reisner
谢谢。没事了,我发现可以使用“test -t”选项检测tty。我无法确定是否指定了“-i”,但“-t”至少会告诉我是否存在tty,如果失败,我可以指示重新运行以带上“-ti”。 - hookenz
不确定为什么会被踩,但我已经澄清了我想要检测的是入口脚本。 - hookenz
1个回答

10

entrypoint.sh:

#!/bin/bash

set -e

if [ -t 0 ] ; then
    echo "(interactive shell)"
else
    echo "(not interactive shell)"
fi
/bin/bash -c "$@"

Dockerfile:
FROM debian:7.8

COPY entrypoint.sh /usr/bin/entrypoint.sh
RUN chmod 755 /usr/bin/entrypoint.sh
ENTRYPOINT ["/usr/bin/entrypoint.sh"]
CMD ["/bin/bash"]

构建镜像:
$ docker build -t is_interactive .

以交互方式运行镜像:

$ docker run -ti --rm is_interactive "/bin/bash"
(interactive shell)
root@dd7dd9bf3f4e:/$ echo something
something
root@dd7dd9bf3f4e:/$ echo $HOME
/root
root@dd7dd9bf3f4e:/$ exit
exit

以非交互方式运行图像:
$ docker run --rm is_interactive "echo \$HOME"
(not interactive shell)
/root
$

这个 stackoverflow答案 帮助我找到了 [ -t 0 ]

8
根据我的测试,这将告诉你是否传递了“-t”选项,但不会告诉你是否传递了“-i”。 - javabrett
您还需要[ -t 1 ]以检测交互模式。Docker运行中的--tty选项只是告诉Docker分配一个tty,但并不意味着您可以得到一个shell。因此,为了完整起见,您需要像[[ -t 0 && -t 1 ]]这样的内容来确保即使使用tty运行映像,但传递了--detach选项,仍然可以检测到这是非交互式会话,并执行相应操作。 - smac89

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接