Jenkins没有等待调用带有expect的bash脚本
我有一份Jenkins的工作,在ExecuteShell窗口中,我调用了一个将文件复制到某个主机的小应用程序 问题是:如果我运行下面显示为./relmanager的脚本。。。通过控制台上的SSH手动连接到运行Jenkins的主机,一切正常,如:Jenkins没有等待调用带有expect的bash脚本,bash,shell,jenkins,expect,Bash,Shell,Jenkins,Expect,我有一份Jenkins的工作,在ExecuteShell窗口中,我调用了一个将文件复制到某个主机的小应用程序 问题是:如果我运行下面显示为./relmanager的脚本。。。通过控制台上的SSH手动连接到运行Jenkins的主机,一切正常,如: [{USER}@{JENKINS_SERVER} release_manager]$ ./relmanager {USER} {PASSWD} u 2014_12_040 i 10.83.206.44 > Verifying configurati
[{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分钟就退出
以下是我所拥有的:executeshell看起来像:
#!/bin/bash
...
#(variables assigned here)
cd $RELEASE_MANAGER
./relmanager $SVN_USER $SVN_PASSWD u $PS_REL i $HOST_IP_ADDR
...
我知道用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
...
一旦用户发生更改或与脚本的交互完成,Jenkins就会关闭SSH连接。在设计脚本时,要确保脚本在Jenkins中完成。通过这样做,您将确保传输不会中断。基本上:如果您的脚本将expect脚本与 spawn-noecho ssh-oStrictHostKeyChecking=no$user@$ip 发送 您发送的内容实际上是发送到正在运行的bash脚本,而不是发送到生成的ssh,因为Jenkins正在关闭生成的ssh 我找到的解决方案是: 1-让jenkins用户通过ssh(不通过passwd)在本地主机上访问自己的用户
2-在bash脚本中执行:ssh-user@jenkins-主机期望……是否等待10秒后放弃?更改超时值是否会改变它在放弃之前等待的时间?最好设置一个密钥,这样您就不会使用密码登录。@EtanReisner,使用Jenkins,它从不等待10秒,几乎是立即的,尽管我看到在目标主机上创建了文件夹并创建了3个文件,第一个和第二个文件只有很少的KB,第三个从未完成修剪,因为它大于20MB@stark,我知道会的。问题是这个应用程序非常复杂,有几个用户在使用它。让jenkins像在普通终端上那样等待会很好…你试过改变超时吗?我仍然相信这会奏效。使用密钥不会改变超时/等行为,这只意味着您不需要使用expect来编写scp脚本。