【问题标题】:Jenkins not waiting on call to a bash script with expect詹金斯没有等待调用带有期望的bash脚本
【发布时间】:2015-02-12 13:25:33
【问题描述】:

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

问题是:如果我通过控制台上的 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 分钟...

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

#!/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:

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

#!/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
...

【问题讨论】:

  • 等待十秒钟然后放弃吗?更改timeout 的值是否会改变放弃前的等待时间?
  • 最好设置一个密钥,这样你就不用密码登录了。
  • @EtanReisner,使用 Jenkins 它从不等待 10 秒,几乎是立即,虽然我看到在目标主机上,创建了文件夹并创建了 3 个文件,第一个和第二个文件只有几个 KB,第三个永远不会完成(修剪),因为它大于 20MB
  • @stark,我知道会的。问题是该应用程序非常复杂,并且由多个用户使用。让詹金斯像在普通终端上那样等待会很棒......
  • 您是否尝试过更改超时时间?我仍然打赌那工作。并且使用密钥不会更改超时/等。行为它只是意味着你不需要使用 expect 来编写scp 的脚本。

标签: bash shell jenkins expect


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    我找到的解决方案是: 1-让 jenkins 用户在本地主机上通过 ssh w/o passwd 到他自己的用户

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

    【讨论】:

      猜你喜欢
      • 2017-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多