2016-12-05 3 views
3

У меня есть питон скрипт (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 [email protected] 'cmd /c cd C:\stage && test.bat'" 
retval=subprocess.call(cmd,shell=True) 
print retval 

В Дженкинс, у меня есть работа с выполнить оболочку следующим образом:

#!/bin/sh 
./myscript.py 

Проблема: Консоль Jenkins показывает только «Я вижу это сообщение на выходе консоли Jenkins». Если есть какой-либо вывод из вызова подпроцесса, он не выводит его на консоль.

Если я замаскирован сервером A и запускаю ту же команду (./myscript.py) в оболочке, я могу видеть вывод вызова подпроцесса.

Как распечатать этот вывод вызова подпроцесса на консоли Jenkins?

FYI: Как вы можете видеть из моей команды, вызов подпроцесса запускает пакетный файл на окнах; Jenkins работает на Linux; Существует SSH установка между двумя машинами ..

Edit: Мой test.bat выглядит следующим образом:

echo off 
RMDIR /S /Q C:\Test 

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

если я запускаю этот пакетный файл локально на сервере окон, он возвращает 1 (потому что я держу файл открытым в тестовой папке)

Но когда скрипт python вызывает этот командный файл, используя вызов подпроцесса, все, что я получаю, это Zero for retval.

Почему это и как исправить это? Если я смогу зафиксировать правильный retval, я могу сделать работу Jenkins неудачной.

Редактировать 12/12: Helllo !! Кто-нибудь! Кто-то! Помогите!

+3

Я подозреваю, что ваша проблема заключается в использовании sshpass. Это создаст собственный tty, чтобы обмануть ssh, чтобы позволить интерактивный сеанс. Он также устанавливает код возврата, основанный на успехе соединения, а не результат выполнения команды внутри ssh. Можете ли вы попробовать использовать ssh напрямую, вместо этого разрешаете публичный ключ? –

+0

ok .. попробуй сейчас – user1164061

+0

Не повезло! Я создал открытый ключ и избавился от ssh pass. Я все равно получаю тот же результат ... :-( – user1164061

ответ

3

TL; DR

Исправление состоит в том, чтобы использовать некоторое условное выполнение (оператор ||) на rmdir, чтобы исправить возвращаемый уровень ошибок.

Исследование

Это был необыкновенный человек из-за ошибки, с довольно много изгибов и поворотов! Сначала мы подозревали, что цепочка stdout была сломана каким-то образом, поэтому рассмотрели это, используя явное использование труб в Popen, а затем удалив sshpass из вашей команды и поэтому напрямую используя вывод ssh.

Однако это не помогло, поэтому мы перешли к обратному коду команды. С удаленным sshpassssh должен вернуть результат выполнения команды. Однако это всегда было для вас.

На данный момент я нашел известную ошибку в 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 || echo failure работает, то есть возвращает уровень ошибок, но RMDIR/S/Q C: \ Test && echo success || echo% ERRORLEVEL% не отражает уровень ошибок. Он должен находиться в следующей строке кода – user1164061

-1

Пакетный файл должен поймать вывод из Jenkins и передать его через stdout (echo) в скрипт python.

2

Когда вы выполняете свой скрипт в оболочке, Python устанавливает STDOUT вашей оболочки как STDOUT подпроцесса, поэтому все, что выполняется, печатается на ваш терминал. Я не уверен, почему, но когда вы выполняете в Jenkins, подпроцесс не наследует 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) 
+0

Спасибо за вашу помощь. Но это еще не решает проблему. У меня есть текстовый файл, открытый в C: \ Test; Таким образом, код возврата должен быть 1 из моего test.bat. Но это то, что я получаю: («Получены следующие ошибки из сценария: \ n ', u' ') (' Сценарий возвращен код выхода: ', 0) – user1164061

+0

@slav - Любое предложение, основанное на вашем опыте? – user1164061

4

Интересно, если он должен сделать что-нибудь с стандартным выводом буферизацией Вы можете попробовать установить PYTHONUNBUFFERED перед запуском команды?

export PYTHONUNBUFFERED=true 
Смежные вопросы