问题
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
...
回答1:
Jenkins closes the SSH connection as soon as the user is changed or your interaction with the script is completed. Design your script in such a way that you are waiting for the script to be completed in Jenkins. By doing this, you will ensure that your transfer is not interrupted.
回答2:
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 ....
来源:https://stackoverflow.com/questions/28478611/jenkins-not-waiting-on-call-to-a-bash-script-with-expect