我有一个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
...
答案 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 ....