作为自由式作业的一部分,我无法在容器内以非交互方式运行 repo。
它提示输入用户名和电子邮件。我通过 git config --global
解决了这个问题工作里面。
但随后它会进行颜色测试,并且会无限期地挂起。
查看 repo 的源代码,我看到了这个
if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror:
if opt.config_name or self._ShouldConfigureUser():
self._ConfigureUser()
self._ConfigureColor()
所以,我在容器内运行了以下内容:
python -C "import os; print os.isatty(0), os.isatty(1)"
果然,它打印出了
True True
查看 Jenkins 日志,它使用
--tty
启动容器指定,并且似乎无法配置该选项。我找不到
bash
强制脚本在非交互式 shell 中运行的选项。如果我将上面的 python 行放在一个文件中并使用几乎任何命令和选项的组合执行它,它仍然会打印出 True True
我看到不同的唯一方法是如果我使用 I/O 重定向
bash <a.sh
打印出
False True
- 即 stdin
不是 tty,并且bash <a.sh >a.log
打印
False False
.对于复杂的脚本,使用
bash <script
有什么问题吗?方法?有谁知道 jenkins 的魔法来防止使用
--tty
启动 docker ?我知道
--tty
是罪魁祸首。我在本地构建容器并运行以下$ docker run repotest python -c "import os;print os.isatty(0), os.isatty(1)"
False False
$ docker run --tty repotest python -c "import os;print os.isatty(0), os.isatty(1)"
True True
运行版本:
我正在使用“在 docker 容器内构建”选项。
最佳答案
运行 bash 脚本 repo_script.sh
“非交互式”,或者更准确地说,没有与标准流关联的终端,您可以简单地运行脚本
repo_script.sh < /dev/null 2>&1 | cat
假设你想以你看到它运行的方式查看输出,就像
repo_script.sh
.通过将标准输出和错误传送到不同的进程,文件描述符显示为管道而不是 TTY 到 repo_script.sh
。 .你也可以直接输出到一个文件,甚至到/dev/null
如果您不关心输出: log_file=/dev/null
repo_script.sh < /dev/null > "${log_file}" 2>&1
运行脚本为
bash < repo_script.sh | cat
可能也会起作用,尽管这是非常不正统的,而且在我看来,运行脚本只是为了打破 TTY 与标准输入的关联。从脚本引擎的角度来看,从文件中读取脚本程序与从标准输入中读取脚本程序是不同的(通常,如果它是终端,则不可搜索),因此可能会有一些细微的差异可能会让您陷入困境意想不到的方式。这种方式不能清楚地将您的意图传达给需要理解您的代码的下一个人,并且可能由于外来的头部抓挠而导致该人部分脱发。
不需要任何 bash 选项,仅使用上述解释 shell 中的输出方向是一种易于理解的、多平台兼容的标准约定,用于更改标准流关联。
附言我认为您的 repo 脚本只需测试标准输入是否为 TTY 就足够了。在我看来,那个剧本的作者在那里思考得不够深入。如果您没有与标准输入关联的终端设备,那么等待输入根本没有用,您可以确定一切都需要在没有用户交互的情况下运行,或者如果不可能,则停止并出现错误。
关于docker - 如何在 Jenkins 作业中从容器内的脚本运行 repo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53125117/