Jenkins没有等待预期的bash脚本

时间:2015-02-12 13:25:34

标签: bash shell jenkins expect

我有一个Jenkins工作,在“执行shell”窗口中,我正在调用一个将文件复制到某个主机的小应用程序。

问题是:如果我在运行Jenkins的主机上通过SSH手动运行脚本(如下所示./relmanager ...),一切正常,如:

[{USER}@{JENKINS_SERVER} release_manager]$ ./relmanager {USER} {PASSWD} u 2014_12_040 i 10.83.206.44
> Verifying configuration files...
spawn scp -oStrictHostKeyChecking=no -C -r 2014_12_040 root@10.83.206.44:/srv/releases/
Password:
fpga-rw.tgz                100% 7587     7.4KB/s   00:00
resetclear.tgz             100%  287     0.3KB/s   00:00
....

但是如果我让Jenkins为我运行它,似乎它不会等待并立即退出,我在作业的控制台输出上看到了这一点:(请注意,我使用set - / + x来查看命令)

+ ./relmanager {USER} {PASSWD} u 2014_12_040 i 10.83.206.44
> Verifying configuration files...
spawn scp -oStrictHostKeyChecking=no -C -r 2014_12_040 root@10.83.206.44:/srv/releases/
Password: + set +x

没有其他任何事情可以做,只是退出而不等待副本需要1-2分钟......

这就是我所拥有的:“执行shell”看起来像:

#!/bin/bash
...
#(variables assigned here)
cd $RELEASE_MANAGER
./relmanager $SVN_USER $SVN_PASSWD u $PS_REL i $HOST_IP_ADDR
...

我知道应用程序relmanager(用bash编写)在内部调用expect脚本。在应用程序'relmanager'中:

relmanager_etc/copy_expect $IP $REL_NAME

'copy_expect'脚本的内容:

#!/usr/bin/expect
set timeout 10
set IP [lindex $argv 0]
set REL_NAME [lindex $argv 1]
spawn scp -oStrictHostKeyChecking=no -C -r $REL_NAME root@$IP:/srv/releases/
expect "Password:"
send "root\r";
interact

我做错了什么?


更新1:

即使我将expect脚本直接添加到Jenkins,它也不会等待命令完成。在expect脚本中更改超时也不会改变行为:

#!/bin/bash
...
#(variables defined here)
./copy_expect $IP $REL_NAME
...

更新2:

将exp_internal添加到expect脚本以显示日志(来自Etan Reisner的提示):

在詹金斯上运行:

spawn scp -oStrictHostKeyChecking=no -C -r 2014_12_040 root@10.83.206.44:/srv/releases/
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {13601}

expect: does "" (spawn_id exp6) match glob pattern "*assword:"? no
Password: 
expect: does "Password: " (spawn_id exp6) match glob pattern "*assword:"? yes
expect: set expect_out(0,string) "Password:"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "Password:"
send: sending "root\r" to { exp6 }
spawn id exp6 sent <\r\n>

interact: received eof from spawn_id exp0
write() failed to write anything - will sleep(1) and retry...
write() failed to write anything - will sleep(1) and retry...

同样的事情,但通过终端运行:

[{USER}@{JENKINS_SERVER} release_manager]$ ./copy_expect 10.83.206.44 2014_12_040
spawn scp -oStrictHostKeyChecking=no -C -r 2014_12_040 root@10.83.206.44:/srv/releases/
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {27464}

expect: does "" (spawn_id exp6) match glob pattern "*assword:"? no
Password:
expect: does "Password: " (spawn_id exp6) match glob pattern "*assword:"? yes
expect: set expect_out(0,string) "Password:"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "Password:"
send: sending "root\r" to { exp6 }
tty_raw_noecho: was raw = 0  echo = 1
spawn id exp6 sent <\r\n>

spawn id exp6 sent <\rfpga-rw.tgz                                                                                                                  0%    0     0.0KB/s   --:-- ETA\rfpga-rw.tgz                                                                                                                100% 7587     7.4KB/s   00:00    \r\n>
fpga-rw.tgz                                                                                                                100% 7587     7.4KB/s   00:00
spawn id exp6 sent <\rresetclear.tgz                                                                                                               0%    0     0.0KB/s   --:-- ETA\rresetclear.tgz                                                                                                             100%  287     0.3KB/s   00:00    \r\n>
resetclear.tgz                                                                                                             100%  287     0.3KB/s   00:00
...

2 个答案:

答案 0 :(得分:0)

一旦用户更改或您与脚本的交互完成,Jenkins就会关闭SSH连接。设计脚本的方式是等待在Jenkins中完成脚本。通过这样做,您将确保您的转移不会中断。

答案 1 :(得分:0)

基本上:如果你的脚本使用了期望脚本

spawn -noecho ssh -oStrictHostKeyChecking = no $ user @ $ ip 发送......

你“发送”的内容实际上是发送到你正在运行的bash脚本,而不是发送到ssh,因为Jenkins正在关闭生成的ssh。

我找到的解决方案是:  1-让jenkins用户将ssh w / o passwd发送给他在本地主机上的用户

在你的bash脚本中执行:ssh your-user @ jenkins-host expect ....