詹金斯很新,我有一个简单但烦人的问题。当我在Jenkins上运行作业(Build)时,我正在触发ruby命令来执行我的测试脚本。
问题是Jenkins没有从控制台实时显示输出。这是触发日志。
Building in workspace /var/lib/jenkins/workspace/foo_bar
No emails were triggered.
[foo_bar] $ /bin/sh -xe /tmp/hudson4042436272524123595.sh
+ ruby /var/lib/jenkins/test-script.rb
基本上它会挂起此输出,直到构建完成,而不是显示完整输出。有趣的是,这不是一致的行为,有时它的工作原理应该如此。但大多数时候没有实时的控制台输出。
Jenkins版本:1.461
答案 0 :(得分:47)
澄清一些答案。
ruby
或python
或任何合理的脚本语言都会缓冲输出;这是为了最小化IO;写入磁盘很慢,写入控制台很慢...... flush()
。例如写一个没有换行符的字符串然后sleep()
在sleep()
完成之后才会写任何内容(我只使用sleep
作为示例,随意替换任何其他昂贵的系统调用)。e.g。这将等待8秒,打印一行,再等5秒,打印第二行。
from time import sleep
def test():
print "ok",
time.sleep(3)
print "now",
time.sleep(5)
print "done"
time.sleep(5)
print "again"
test()
ruby
,STDOUT.sync = true
,打开autoflush
;对STDOUT
的所有写入后跟flush()
。这可以解决您的问题,但会产生更多的IO。
STDOUT.sync = true
对于python
,您可以使用python -u
或环境变量PYTHONUNBUFFERED
使stdin/stdout/stout
无法缓冲,但there are other solutions不会更改stdin
或stderr
export PYTHONUNBUFFERED=1
perl
,您有autoflush
autoflush STDOUT 1;
答案 1 :(得分:10)
确保你的脚本正在刷新stdout,stderr。 在我的情况下,我有一个类似于你描述的抛光问题,但我使用的是python。 python下面的代码为我修复了它:
import sys
sys.stdout.flush()
我不是Ruby代码,但谷歌揭示了以下内容:
$stdout.flush
答案 2 :(得分:5)
在我看来python -u
也可以。
E.g。在批处理命令
中python -u foo.py
答案 3 :(得分:4)
这里最简单的解决方案是打开同步缓冲区输出。 @Craig在他的回答中写到的东西,但是一行解决方案将覆盖整个脚本,并且不需要你多次刷新缓冲区。
只需写下
STDOUT.sync = true
背后的逻辑很简单,为避免使用IO操作多次缓冲输出。要禁用此功能
STDOUT.sync = false
这是Ruby解决方案。
答案 4 :(得分:3)
其他每个答案都针对一个或另一个程序,但我在这里找到了更通用的解决方案:
https://unix.stackexchange.com/a/25378
您可以使用stdbuf
来改变任何程序的缓冲行为。
在我的情况下,我通过tee
和grep
来管道输出来自shell脚本,以将行拆分为控制台或基于内容的文件。如OP所述,控制台正在悬挂。这解决了它:
./slowly_parse.py login.csv |tee >(grep -v LOG: > out.csv) | stdbuf -oL -eL grep LOG:
最终我发现我可以将--line-buffered
传递给grep以获得相同的结果:
./slowly_parse.py login.csv |tee >(grep -v LOG: > out.csv) | grep --line-buffered LOG:
答案 5 :(得分:1)
其他答案是正确的,说您需要确保标准输出不被缓冲。
另一件需要注意的事情是Jenkins本身会逐行缓冲。如果您有一个缓慢运行的进程,它会发出单个字符(例如,为成功测试打印.
的nunit测试套件摘要,并为错误打印E
),您将看不到任何内容行尾。
[我的Jenkins 1.572运行在Windows机箱上。]
答案 6 :(得分:1)
对于某些命令,包括tee
,最好的解缓冲选择是来自unbuffer
程序包的名为expect
的程序。
用法示例:
代替
somecommand | tee /some/path
做
somecommand | unbuffer -p tee /some/path
来源和更多信息:
答案 7 :(得分:0)
操作系统本质上是缓冲输出数据,以节省CPU,Jenkins也是如此。
看起来您正在使用shell命令来运行Ruby脚本 -
我建议直接通过专用插件运行你的Ruby脚本:
(可能需要安装)
答案 8 :(得分:0)
Python会缓冲其输出轨迹,并在脚本末尾打印它,以最大程度地减少在控制台上的写入,因为写入控制台的速度很慢。
跟踪后可以使用以下命令。它将所有跟踪刷新到控制台,该跟踪在该命令之前排队。
sys.stdout.flush()