期望脚本的本地 运行 工作正常,但是当 运行 通过 gitlab CI 时挂起

A local run of expect script works fine, but hangs when ran through gitlab CI

我正在编写一个 expect 文件来连接以使用如下所示的脚本来处理与远程设备的交互,但我遇到了一些问题。主要是,当我 运行 脚本独立或交互(在 运行ner 上)时,它按我希望的方式工作,但是当我使用 Gitlab [=41= 插入代码进行测试时] 在其中一个 运行ners 上,它有以下问题:

  1. 命令 spawn /usr/bin/scp $rsaFile remote:/var/root/id_rsa.pub 似乎没有出现在 CI 日志中 (尽管出现了第一个 spawn /usr/bin/ssh remote 命令)-我 怀疑它根本没有被调用。
  2. 相同的 spawn 命令持续给我以下消息,直到脚本在下一个 interact 命令停止执行:"Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\n"
  3. interact 抱怨 spawn id exp0 not open(我认为这可能是因为 scp 命令无法正常工作)

代码如下:

spawn /usr/bin/ssh remote

expect {
    -re ".*assword:.*" {
        exp_send "password\r"; 
        exp_continue
    }
    -re ".*sh.*" {
        exp_send "mount -uw /\r";
        exp_send "nvram -somecommand"
        exp_send "exit\r"
    }
}

interact

# Copy over the key
set rsaFile "/var/root/Resources/id_rsa.pub"
spawn /usr/bin/scp $rsaFile remote:/var/root/id_rsa.pub;

expect {
    # 1&2 were added to the original script for debugging purposes
    -re "^id_rsa.pub.*" { #1: output I'd expect in case of successful scp
        exp_send "exit\r"
    }
    -re ".*assword:.*" {
        exp_send "password\r";
        exp_send "exit\r"
    }
    -re "Warning:.*Warning.*Warning.*" { #2: to debug the expect hanging
        exp_send "exit\r"
    }
}

interact;

这是错误消息(预计处于调试模式):

spawn /usr/bin/ssh remote

parent: waiting for sync byte

parent: telling child to go ahead

parent: now unsynchronized from child

spawn: returns {24373}

Gate keeper glob pattern for '.*assword:.*' is '*assword:*'. Activating booster.
Gate keeper glob pattern for '.*sh.*' is '*sh*'. Activating booster.

expect: does "" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no

".*sh.*"? Gate "*sh*"? gate=no

Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.

expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\n" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no

".*sh.*"? Gate "*sh*"? gate=no

root@fe80::cccc:48ff:fe33:3344%en4's password: 

expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nroot@fe80::cccc:48ff:fe33:3344%en4's password: " (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=yes re=yes

expect: set expect_out(0,string) "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nroot@fe80::cccc:48ff:fe33:3344%en4's password: "

expect: set expect_out(spawn_id) "exp6"

expect: set expect_out(buffer) "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nroot@fe80::cccc:48ff:fe33:3344%en4's password: "

send: sending "password\r" to { exp6 }

expect: continuing expect

expect: does "" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no

".*sh.*"? Gate "*sh*"? gate=no

expect: does "\r\n" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no

".*sh.*"? Gate "*sh*"? gate=no

expect: does "\r\n\u001b[?1034h" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no

".*sh.*"? Gate "*sh*"? gate=no

-sh-3.2# 

expect: does "\r\n\u001b[?1034h-sh-3.2# " (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no

".*sh.*"? Gate "*sh*"? gate=yes re=yes

expect: set expect_out(0,string) "\r\n\u001b[?1034h-sh-3.2# "

expect: set expect_out(spawn_id) "exp6"

expect: set expect_out(buffer) "\r\n\u001b[?1034h-sh-3.2# "

send: sending "mount -uw /\r" to { exp6 }

send: sending "nvram -some-command" to { exp6 }

send: sending "exit\r" to { exp6 }

interact: received eof from spawn_id exp0

parent: waiting for sync byte

parent: telling child to go ahead

parent: now unsynchronized from child

spawn: returns {24376}

Gate keeper glob pattern for '^id_rsa.pub.*' is 'id_rsa?pub*'. Activating booster.
Gate keeper glob pattern for '.*assword:.*' is '*assword:*'. Activating booster.
Gate keeper glob pattern for 'Warning:.*Warning.*Warning.*' is ''. Not usable, disabling the performance booster.

expect: does "" (spawn_id exp1) match regular expression "^id_rsa.pub.*"? Gate "id_rsa?pub*"? gate=no

".*assword:.*"? Gate "*assword:*"? gate=no

"Warning:.*Warning.*Warning.*"? (No Gate, RE only) gate=yes re=no

expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\n" (spawn_id exp1) match regular expression "^id_rsa.pub.*"? Gate "id_rsa?pub*"? gate=no

".*assword:.*"? Gate "*assword:*"? gate=no

"Warning:.*Warning.*Warning.*"? (No Gate, RE only) gate=yes re=no

expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\n" (spawn_id exp1) match regular expression "^id_rsa.pub.*"? Gate "id_rsa?pub*"? gate=no

".*assword:.*"? Gate "*assword:*"? gate=no

"Warning:.*Warning.*Warning.*"? (No Gate, RE only) gate=yes re=no

expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\n\r\n\r\n\r\n" (spawn_id exp1) match regular expression "^id_rsa.pub.*"? Gate "id_rsa?pub*"? gate=no

".*assword:.*"? Gate "*assword:*"? gate=no

"Warning:.*Warning.*Warning.*"? (No Gate, RE only) gate=yes re=yes

expect: set expect_out(0,string) "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\n\r\n\r\n\r\n"

expect: set expect_out(spawn_id) "exp1"

expect: set expect_out(buffer) "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\n\r\n\r\n\r\n"

send: sending "exit\r" to { exp1 }

interact: spawn id exp0 not open
    while executing
"interact"
    (file "./Resources/Setup.command" line 44)

ERROR: Build failed: exit status 1

如有任何帮助,我们将不胜感激!提前致谢 顺便说一句——这个问题让我很烦,所以我想弄清楚,因为这是我第一个 post 堆栈溢出。 :)

这样试试:

spawn /usr/bin/ssh remote

expect {
    -re ".*assword:.*" {
        exp_send "password\r";
        exp_continue
    }
    -re ".*-sh-.*" {
        exp_send "mount -uw /; nvram -somecommand; exit\r"
        exp_continue
    }
    eof {}
}
wait

set rsaFile "/var/root/Resources/id_rsa.pub"
spawn /usr/bin/scp $rsaFile remote:/var/root/id_rsa.pub;

expect {
    -re ".*assword:.*" {
        exp_send "password\r";
        exp_continue
    }
    eof {}
}
wait

您的 interact 可能会失败,因为那时 spawned 进程可能已经退出,显然它无法 交互 死亡 过程。

对于你的脚本,我的expect eof和你的interact基本上是一样的效果。他们都在等待 spawned 过程完成。这里的区别是时机。并且 expect eofspawned 进程退出时不会产生错误。