詹金斯没有等待带有期望的bash脚本的调用 [英] Jenkins not waiting on call to a bash script with expect
问题描述
我有一个Jenkins作业,并且在执行外壳"窗口中,我正在调用一个将文件复制到某个主机的小型应用程序.
问题是:如果我通过SSH在控制台上手动通过SSH手动运行脚本(在下面显示为./relmanager ...),到运行Jenkins的主机,则一切正常,例如:
[{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分钟就退出...
这就是我所拥有的:执行外壳"如下所示:
#!/bin/bash
...
#(variables assigned here)
cd $RELEASE_MANAGER
./relmanager $SVN_USER $SVN_PASSWD u $PS_REL i $HOST_IP_ADDR
...
我知道应用程序relmanager(用bash编写)在内部调用了期望脚本.在应用程序"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:
即使我直接将期望脚本添加到Jenkins,它也不会等待命令完成.在Expect脚本中更改超时也不会更改行为:
#!/bin/bash
...
#(variables defined here)
./copy_expect $IP $REL_NAME
...
更新2:
在期望脚本中添加exp_internal以显示日志(来自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
...
基本上:如果您的脚本使用带有-
spawn -noecho ssh -oStrictHostKeyChecking = no $ user @ $ ip 发送...
您发送"的内容实际上发送到您正在运行的bash脚本,而不发送到生成的ssh,因为Jenkins正在关闭生成的ssh.
我找到的解决方案是: 1-让jenkins用户在本地主机上不向其自己的用户ssh传递密码
2-在您的bash脚本中执行:ssh your-user @ jenkins-host期望....
I have a Jenkins job and on the "Execute shell" window I am calling a small application that copies files to some host.
The problem is: If I run the script (shown bellow as ./relmanager ...) manually via SSH on a console to the host where Jenkins is running, everything works fine, like:
[{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
....
But if I ask Jenkins to run it for me, it seems that it doesn't wait and quits immediately, and I see this on the console output of the job: (note that I used set -/+ x to see the commands)
+ ./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
And nothing else is done, just quits without waiting the ~1-2mins the copy takes...
Here is what I have: The "Execute shell" looks like:
#!/bin/bash
...
#(variables assigned here)
cd $RELEASE_MANAGER
./relmanager $SVN_USER $SVN_PASSWD u $PS_REL i $HOST_IP_ADDR
...
I know that the application relmanager (written in bash) internally calls an expect script. Inside the application 'relmanager':
relmanager_etc/copy_expect $IP $REL_NAME
And contents of 'copy_expect' script:
#!/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
What am I doing wrong?
UPDATE 1:
Even if I add directly the expect script to Jenkins, it also does not wait for the command to complete. Changing timeout inside the expect script does not change the behavior as well:
#!/bin/bash
...
#(variables defined here)
./copy_expect $IP $REL_NAME
...
UPDATE 2:
Adding exp_internal to the expect script to show log (Tip from Etan Reisner):
Running on jenkins:
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...
And the same thing but running via terminal:
[{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
...
basically : if your script uses expect script with
spawn -noecho ssh -oStrictHostKeyChecking=no $user@$ip send ...
what you "send" is actually sent to the bash script you are running and NOT to the ssh spawned because Jenkins is closing the spawned ssh .
The solution I found is : 1- let the jenkins user to ssh w/o passwd to his own user at local host
2- in your bash script do: ssh your-user@jenkins-host expect ....
这篇关于詹金斯没有等待带有期望的bash脚本的调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!