我从Jenkinsfile
运行以下命令。但是,我收到错误"输入设备不是TTY" 。
docker run -v $PWD:/foobar -it cloudfoundry/cflinuxfs2 /foobar/script.sh
有没有办法在不进行交互模式的情况下从Jenkinsfile
运行脚本?
我基本上有一个名为script.sh
的文件,我想在Docker容器中运行。
答案 0 :(得分:390)
从cli中删除-it
以使其不具有交互性并删除TTY。如果您不需要,例如在Jenkins或cron脚本中运行命令,你应该这样做。
或者,如果您输入的管道输入管道命令并非来自TTY,您可以将其更改为-i
。如果您的命令行中有xyz | docker ...
或docker ... <input
,请执行此操作。
或者,如果您需要TTY支持但未在输入设备上使用,则可以将其更改为-t
。这样做是为了对日志中的输出进行颜色格式化,或者以后用适当的终端连接到容器时。
或者,如果您需要交互式终端并且未在Linux或MacOS上的终端中运行,请使用其他命令行界面。据报道,PowerShell在Windows上包含此支持。
什么是TTY?它是一个支持彩色输出,转义序列,移动光标等的终端接口,它来自于连接到大型机的哑终端的旧时代。今天它由Linux命令终端和ssh接口提供。请参阅wikipedia article for more details。
答案 1 :(得分:48)
对于那些在Windows上遇到此错误和git bash的人,只需使用import UIKit
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ChecklistItem", for: indexPath)
let label = cell.viewWithTag(1000) as! UILabel
let image = cell.viewWithTag(1001) as! UIImageView
let margins = cell.contentView.layoutMarginsGuide
if indexPath.row == 0 {
label.text = "First row"
} else if indexPath.row == 1 {
label.text = "Second row"
image.image = UIImage(named: "test")
} else if indexPath.row == 2 {
label.text = "Third row"
label.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
} else if indexPath.row == 3 {
label.text = "Fourth row"
}
return cell
}
}
完美运行的PowerShell。
答案 2 :(得分:31)
如果你(就像我)在Windows上使用git bash,你只需要输入
winpty
在“泊坞线”之前:
winpty docker exec -it some_cassandra bash
答案 3 :(得分:23)
我相信你需要在TTY中为docker分配一个TTY(-t
选项)。 Jenkins在TTY中执行 not 的工作。
话虽如此,您在Jenkins中运行的脚本也可能需要在本地运行。在这种情况下,分配TTY非常方便,因此在本地运行时可以发送 ctrl + c 等信号。
要解决此问题,请使您的脚本可选择使用-t
选项,如下所示:
test -t 1 && USE_TTY="-t"
docker run ${USE_TTY} ...
答案 4 :(得分:21)
这不是您要问的,而是:
-T键将帮助使用 docker-compose exec!
的人。docker-compose -f /srv/backend_bigdata/local.yml exec -T postgres backup
答案 5 :(得分:4)
使用docker-compose exec -T通过Jenkins为我解决了这个问题
docker-compose exec -T containerName php script.php
答案 6 :(得分:3)
如果使用Windows,请尝试使用cmd,对我来说它可行。检查docker是否已启动。
答案 7 :(得分:1)
只要不指定要挂载的卷(例如“。:/ mountpoint”或“ $ {pwd}:/ mountpoint”),winpty就可以工作
我发现最好的解决方法是使用Visual Code Studio中的git-bash插件,并使用终端启动和停止容器或docker-compose。
答案 8 :(得分:1)
我知道这不是直接回答当前的问题,而是针对任何遇到此问题的人,这些人正在使用WSL在Windows和cmder或conmumu上运行Docker。
诀窍不是使用Windows上/ mnt / c / Program Files / Docker / 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终端会话进行交互式连接。
答案 9 :(得分:0)
使用“ 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”时,一切正常。
答案 10 :(得分:0)
下面显示的我的Jenkins管道步骤失败,并出现相同的错误。
steps {
echo 'Building ...'
sh 'sh ./Tools/build.sh'
}
在我的“ build.sh ”脚本文件中,“ docker run ”命令输出此错误,该错误由Jenkins作业执行。但是,当脚本在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
答案 11 :(得分:0)
在詹金斯,我使用 docker-compose exec -T
例如:-
docker-compose exec -T app php artisan migrate
答案 12 :(得分:0)
对于那些使用 Pyinvoke 的人,请参阅 this documentation,万一链接失效,我将在此处联合:
<块引用>在 99% 的情况下,将 pty=True 添加到您的 run 调用将使事情按您的预期工作。继续阅读为什么会这样(以及为什么 pty=True 不是默认值)。
<块引用>命令行程序通常会根据是否存在控制终端来改变行为;一个常见的例子是使用或不使用彩色输出。当您的输出的接收者是终端上的人类时,您可能需要使用颜色、定制线条长度以匹配终端宽度等。
<块引用>相反,当您的输出被发送到另一个程序(shell 管道、CI 服务器、文件等)时,颜色转义码和其他特定于终端的行为可能会导致不必要的垃圾。
<块引用>Invoke 的用例涵盖了以上两种情况——有时您只想直接显示数据,有时您只想将其捕获为字符串;通常你两者都想要。正因为如此,没有“正确”的默认行为:使用伪终端——无论哪种方式都会给一些大量用例带来不便。
<块引用>对于不关心的用例,没有伪终端的直接调用更快更干净,所以它是默认的。