2016-12-05 72 views
3

我有一个python脚本(myscript.py)如下:詹金斯不打印Python脚本的输出在控制台

#!/bin/python 
import os 
import optparse 
import subprocess 
import sys 
sys.stdout.flush() 

print("I can see this message on Jenkins console output") 
cmd="sshpass -p 'xxx' ssh [email protected] 'cmd /c cd C:\stage && test.bat'" 
retval=subprocess.call(cmd,shell=True) 
print retval 

在詹金斯,我有如下执行shell工作:

#!/bin/sh 
./myscript.py 

问题: Jenkins控制台只显示“我可以在Jenkins控制台输出上看到此消息”。 如果子流程调用有任何输出,它不会在控制台上打印出来。

如果我putty到服务器A并在shell上运行相同的命令(./myscript.py),我可以看到子进程调用的输出。

如何在Jenkins控制台上打印子流程调用的输出?

仅供参考:您可以从我的命令中看到,子进程调用正在Windows上运行批处理文件; Jenkins正在Linux上运行;有两台机器之间的ssh设置..

编辑: 我test.bat的是这样的:

echo off 
RMDIR /S /Q C:\Test 

IF %ERRORLEVEL% NEQ 0 (
    ECHO Could not delete 
    EXIT /b %ERRORLEVEL% 
) 

如果我Windows服务器上本地运行这个批处理文件,则返回1(因为我拿着一个文件在测试文件夹中打开)

但是,当python脚本使用子进程调用来调用这个批处理文件时,我得到的是一个零的retval。

这是为什么,以及如何解决这个问题?如果我能捕捉到正确的retval,我可以让Jenkins工作失败。

编辑12/12: Helllo !!任何人!有人!帮帮我!

+3

我怀疑你的问题是使用sshpass。这将设置自己的tty来欺骗ssh,允许交互式会话。它还根据连接的成功设置返回代码,而不是在ssh内运行命令的结果。你可以尝试直接使用ssh,而不是使用公钥授权? –

+0

好的..现在就试试 – user1164061

+0

不行!我创建了一个公共密钥,并清除了ssh pass。我仍然得到相同的结果... :-( – user1164061

回答

3

TL; DR

修复方法是使用rmdir上的一些条件执行(||运算符)来修复返回的错误级别。

调查

这是一个错误的考克,与不少波折!我们最初怀疑标准输出链是以某种方式破碎的,所以通过明确使用Popen中的管道,然后从您的命令中删除sshpass来直接使用ssh的输出。

但是,这并没有诀窍,因此我们继续查看命令的返回代码。通过删除sshpassssh应返回运行的命令的结果。但是,这对你来说总是0。

在这一点上,我发现一个已知的Windows中的错误rmdir(这是rd相同)并不总是正确设置errorlevel。修复方法是使用rmdir上的一些条件执行(||运算符)修复错误级别。

查看batch: Exit code for "rd" is 0 on error as well的全部细节。

+0

再次感谢你! – user1164061

+0

对于查看相同问题的其他人:RMDIR/S/Q C:\ Test && echo success ||回声失败的工作原理,即它返回一个错误级别,但是RMDIR/S/Q C:\ Test && echo success || echo%ERRORLEVEL%不会回显错误级别。它必须位于下一行代码中 – user1164061

-1

该批处理文件必须捕获来自Jenkins的输出并将其通过标准输出(回显)传递给python脚本。

2

当你在shell中执行你的脚本时,Python将你的shell的STDOUT设置为子进程的STDOUT,所以执行的所有东西都会打印到你的终端上。我不知道为什么,但是当你在Jenkins中执行时,子进程不会继承shell的STDOUT,因此它的输出不会显示。

很可能,解决问题的最佳方法是将STDOUT(和STDERR用于较好的度量)PIPE并在处理结束后打印出来。此外,如果您退出时使用您的子流程的退出代码,并且退出代码不是0,它可能会终止您的Jenkins工作。

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, 
        stderr=subprocess.PIPE, shell=True) 
exit_code = p.wait() # wait for it to end 
print('Got the following output from the script:\n', p.stdout.read().decode()) 
print('Got the following errors from the script:\n', p.stderr.read().decode()) 
print('Script returned exit code:', exit_code) 

sys.exit(exit_code) 
+0

谢谢你的帮助。但是这仍然不能解决问题。我在C:\ Test中打开了一个文本文件;所以返回代码应该从我的test.bat中为1。但是,这是我得到:('从脚本得到以下错误:\ n',ü'') ('脚本返回退出代码:',0) – user1164061

+0

@slav - 任何建议基于您的专业知识? – user1164061

4

我不知道是否有做什么标准输出被缓冲 你可以尝试运行命令之前,设置PYTHONUNBUFFERED

export PYTHONUNBUFFERED=true