我有一个python脚本(myscript.py),如下所示:
#!/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 test@testmachine 'cmd /c cd C:\stage && test.bat'"
retval=subprocess.call(cmd,shell=True)
print retval
在jenkins中,我有一个执行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(因为我在Test文件夹中打开了一个文件)
但是当python脚本使用subprocess调用调用这个批处理文件时,我得到的只是一个Zero for retval。
为什么会这样以及如何解决这个问题?如果我能捕获正确的retval,我可以让Jenkins的工作失败。
编辑12/12: Helllo!任何人!有人!救命!
答案 0 :(得分:6)
我想知道是否必须对缓冲的stdout做任何事情
您可以在运行命令之前尝试设置PYTHONUNBUFFERED
吗?
export PYTHONUNBUFFERED=true
答案 1 :(得分:3)
修复是在||
上使用一些条件执行(rmdir
运算符)来修复返回的错误级别。
这是一个臭虫的corker,有很多曲折!我们最初怀疑stdout链是以某种方式被破坏的,所以通过在Popen
中明确使用管道,然后从命令中删除sshpass
并直接使用ssh
的输出来查看它。
但是,这没有做到这一点,所以我们继续查看命令的返回码。删除sshpass
后,ssh
应返回运行的命令的结果。但是,这对你来说总是0。
此时,我发现Windows中的一个已知错误rmdir
(与rd
相同)并不总是正确设置errorlevel
。修复是在||
上使用一些条件执行(rmdir
运算符)来修复错误级别。
答案 2 :(得分:2)
当您在shell中执行脚本时,Python将您的shell的STDOUT设置为子进程的STDOUT,因此执行的所有内容都会打印到您的终端。我不确定原因,但是当你在Jenkins中执行时,子进程不会继承shell的STDOUT,因此不会显示它的输出。
很有可能,解决问题的最佳方法是PIPE
STDOUT(以及STDERR),并在流程结束后打印出来。此外,如果您使用子流程的退出代码退出且退出代码不是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)
答案 3 :(得分:2)
在我的 Jenkins 环境中,使用 unbuffered 参数执行 python 脚本会使输出立即出现。像这样:
python3 -u some_script.py
更多信息来自帮助菜单 (python3 --help
):
-u : force the stdout and stderr streams to be unbuffered;
this option has no effect on stdin; also PYTHONUNBUFFERED=x
答案 4 :(得分:-1)
批处理文件必须捕获Jenkins的输出并通过stdout(echo)传递给python脚本。