如何 运行 在 jenkins 作业中从容器内的脚本回购
How to run repo from a script inside a container in a jenkins job
作为自由式作业的一部分,我无法 运行 在容器内以非交互方式回购。
它提示输入用户名和电子邮件。我通过在作业中执行 git config --global
来解决这个问题。
但随后它进行颜色测试,并无限期挂起。
查看回购的源代码我看到了这个
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 魔法来防止 docker 使用 --tty
启动?
我知道 --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
运行 版本:
- 回购:1.12.37(根据 Ubuntu 16.04 apt-get)
- 詹金斯:2.149
- Cloudbees Docker 插件:1.7.3
- 容器基础是ubuntu:xenial
我正在使用 "Build inside a docker container" 选项。
到 运行 bash 脚本 repo_script.sh
"non-interactively",或者更准确地说,没有与标准流关联的终端,你可以 运行 你的脚本简单作为
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 与标准输入的关联。从脚本引擎的角度来看,从文件中读取脚本程序与从标准输入中读取脚本程序是不同的(通常,如果它是终端,则不可搜索),因此可能存在一些细微的差异 could 可能会以意想不到的方式咬你。这种方式不会将您的意图清楚地传达给需要理解您的代码的下一个人,并且可能会由于无关的头部抓挠而导致该人部分脱发。
不需要任何bash选项,仅使用解释shell中的输出方向,如上所述是一个易于理解、多平台兼容的标准约定更改标准流关联。
P.S。我认为您的 repo 脚本只测试标准输入是否为 TTY 就足够了。在我看来,该脚本的作者在那里考虑得不够深入。如果您没有与标准输入相关联的终端设备,那么等待输入根本没有用,并且您可以确定所有内容都需要 运行 而无需用户从那里进行交互,或者如果不可能则因错误而停止。
作为自由式作业的一部分,我无法 运行 在容器内以非交互方式回购。
它提示输入用户名和电子邮件。我通过在作业中执行 git config --global
来解决这个问题。
但随后它进行颜色测试,并无限期挂起。
查看回购的源代码我看到了这个
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 魔法来防止 docker 使用 --tty
启动?
我知道 --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
运行 版本:
- 回购:1.12.37(根据 Ubuntu 16.04 apt-get)
- 詹金斯:2.149
- Cloudbees Docker 插件:1.7.3
- 容器基础是ubuntu:xenial
我正在使用 "Build inside a docker container" 选项。
到 运行 bash 脚本 repo_script.sh
"non-interactively",或者更准确地说,没有与标准流关联的终端,你可以 运行 你的脚本简单作为
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 与标准输入的关联。从脚本引擎的角度来看,从文件中读取脚本程序与从标准输入中读取脚本程序是不同的(通常,如果它是终端,则不可搜索),因此可能存在一些细微的差异 could 可能会以意想不到的方式咬你。这种方式不会将您的意图清楚地传达给需要理解您的代码的下一个人,并且可能会由于无关的头部抓挠而导致该人部分脱发。
不需要任何bash选项,仅使用解释shell中的输出方向,如上所述是一个易于理解、多平台兼容的标准约定更改标准流关联。
P.S。我认为您的 repo 脚本只测试标准输入是否为 TTY 就足够了。在我看来,该脚本的作者在那里考虑得不够深入。如果您没有与标准输入相关联的终端设备,那么等待输入根本没有用,并且您可以确定所有内容都需要 运行 而无需用户从那里进行交互,或者如果不可能则因错误而停止。