错误“输入设备不是TTY”


425

我正在从中运行以下命令Jenkinsfile。但是,出现错误“输入设备不是TTY”

docker run -v $PWD:/foobar -it cloudfoundry/cflinuxfs2 /foobar/script.sh

有没有一种方法可以在Jenkinsfile不进行交互模式的情况下从中运行脚本?

我基本上有一个名为的文件script.sh,希望在Docker容器中运行。


对于* nix,似乎这里没有解决方案。'docker exec -i'不起作用,'-t'也不起作用。
rjurney18年

1
@rjurney您是否找到了针对docker exec的解决方案?我尝试了-i和-t,但没有成功。docker exec -it mycontainer bash certbot --apache -d www.website.com --email *********@gmail.com --agree-tos -n
Hutch

@Hutch抱歉,我不记得了:(
rjurney

Answers:


639

去除 -it从cli中使其不具有交互性,并删除TTY。如果不需要,例如在Jenkins或cron脚本中运行命令,则应这样做。

或者,您也可以将其更改为-i输入到不是来自TTY的docker命令中的输入。如果您在命令行中有类似xyz | docker ...或这样的内容docker ... <input,请执行此操作。

或者,您可以将其更改为-t想要TTY支持但在输入设备上不可用的情况。这样做是为了对日志中的输出进行彩色格式化,或者用于以后使用适当的终端连接到容器时使用的格式。

或者,如果您需要交互式终端并且不在Linux或MacOS的终端中运行,请使用其他命令行界面。据报道,PowerShell在Windows上包括此支持。


什么是TTY?它是一个终端接口,支持彩色输出,转义序列,移动光标等,这是从老式笨拙的终端连接到大型机的日子开始的。今天,它是由Linux命令终端和ssh接口提供的。有关更多详细信息,请参见Wikipedia文章


10
我在mysql -p不指定密码的情况下结合使用此命令。仅添加-i密码提示时,永远不会出现。仅添加-t提示会出现,但似乎根本不读取输入(即按字面意思打印而不是被提示隐藏),即使按回车也不行。只有ctrl-c可以结束它。以某种方式可以将mysql客户端与docker一起使用吗?
ohcibi '18年

95

对于那些在Windows上遇到此错误和git bash困扰的人,只需使用PowerShell即可-it


12
这不能回答问题。问题是关于Jenkins中的docker,而不是Windows上的git bash。

44
好。是的,而且从未打算这样做。当您搜索此特定错误消息时,该问题会在Google中弹出。我算了一下,最好是有答案的地方比没有拥有它。显然有人发现它有用:)
Piotr Justyna

3
Powershell作为用于Shell操作的TTY的问题在于,它无法正确传递箭头键,如循环命令历史记录的向上箭头。除了缺点之外,效果很好。
Corgalore

2
如果您想继续使用Git Bash,请在另一个问题以下winpty答案
tessafyi

67

这并不是您要问的,但是:

-T键将有助于谁使用人泊坞窗,撰写EXEC!

docker-compose -f /srv/backend_bigdata/local.yml exec -T postgres backup

2
正是我想要的。你知道为什么这样吗?
乌拉德·卡萨赫

6
正是我需要的。根据帮助:-T禁用伪tty分配。默认情况下docker-compose exec 分配一个TTY。
TS

谢啦。我在其中搜索docker-compose!
ADyDyka

这对我有用!
rlorenzo

58

如果您(像我一样)在Windows上使用git bash,则只需将

Winpty

在您的“码头工人线”之前:

winpty docker exec -it some_cassandra bash

您如何下载winpty
Mor Shemesh

6
在询问之前您尝试过吗?我认为它是Git附带的(我的文件

您是对的,这是在C:\Program Files\Git\usr\bin\winpty.exe
Mor Shemesh '18

31

我相信您需要在Docker中处于TTY状态才能分配TTY(该-t选项)。詹金斯不在 TTY中执行其工作。

话虽如此,您可能还希望在Jenkins中运行的脚本在本地运行。在这种情况下,分配TTY真的很方便,因此在本地运行TTY时可以发送ctrl+等信号c

要解决此问题,请使脚本可以选择使用-t选项,如下所示:

test -t 1 && USE_TTY="-t" 
docker run ${USE_TTY} ...

运行时,这个错误发生在我身上docker run…命令的形式由git的钩子引发了生成文件的任务
爱德华·洛佩兹

1
这应该是公认的答案。它实际上以一种普遍适用的方式解决了这个问题
根哈恩

11

当使用'git bash'时,

1)我执行命令:

docker exec -it 726fe4999627 /bin/bash

我有错误:

the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'

2)然后,我执行命令:

winpty docker exec -it 726fe4999627 /bin/bash

我还有另一个错误:

OCI runtime exec failed: exec failed: container_linux.go:344: starting container process caused "exec: \"D:/Git/usr/bin/
bash.exe\": stat D:/Git/usr/bin/bash.exe: no such file or directory": unknown

3)第三,我执行:

winpty docker exec -it 726fe4999627 bash

有效。

当我使用“ powershell”时,一切运行良好。


对于这些问题,我还用bash将我的头撞在墙上几个小时。切换到Powershell,现在一切正常!
David Spenard


1

只要您不指定要挂载的卷(例如“。:/ mountpoint”或“ $ {pwd}:/ mountpoint”),winpty就可以工作

我发现最好的解决方法是在Visual Code Studio中使用git-bash插件,并使用终端启动和停止容器或docker-compose。


1

我知道这不是直接回答当前的问题,而是针对任何遇到此问题的人,这些人正在为Windows和cmder或conmu使用WSL运行Docker。

诀窍不是使用Windows上/ mnt / c / Program Files / Docker / Docker / resources / bin / docker.exe上安装的Docker,而是安装ubuntu / linux Docker。值得指出的是,您不能在WSL中运行Docker本身,但是可以从linux Docker客户端连接到Windows的Docker。

在Linux上安装Docker

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce

在端口2375上连接到Windows的Docker,需要从docker for Windows的设置中启用。

docker -H localhost:2375 run -it -v /mnt/c/code:/var/app -w "/var/app" centos:7

或者设置docker_host变量,该变量将允许您省略-H开关

export DOCKER_HOST=tcp://localhost:2375

现在,您应该能够与tty终端会话进行交互式连接。


0

下面显示的我的Jenkins管道步骤失败,并出现相同的错误。

       steps {
            echo 'Building ...' 
            sh 'sh ./Tools/build.sh'
        }

在我的 ”Jenkins作业执行此错误时, build.sh ”脚本文件中,“ docker run ”命令输出此错误。但是,当脚本在shell终端中运行时,它运行正常。由于发生-t选项传递给docker run命令的错误,据我所知,该命令尝试分配终端,如果没有终端要分配失败,则会发生错误。

就我而言,仅当可以检测到终端时,才将脚本更改为通过-t选项。这是更改后的代码:

DOCKER_RUN_OPTIONS="-i --rm"

# Only allocate tty if we detect one
if [ -t 0 ] && [ -t 1 ]; then
    DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS -t"
fi

docker run $DOCKER_RUN_OPTIONS --name my-container-name  my-image-tag
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.