I'm writing an expect file to connect to handle the interaction with the remote device by using a script that looks something like the following, and I am facing a few problems with it. Mainly, when I run the script stand-alone or interactively (on a runner), it works as I wish, but when I plug in the code for a testing using the Gitlab CI on one of the runners, it has the following problems:
spawn /usr/bin/scp $rsaFile
remote:/var/root/id_rsa.pub
doesn't seem to show up in the CI log
(though the first spawn /usr/bin/ssh remote
command shows up) - I
suspect it's not being called at all."Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\n"
spawn id exp0 not open
(which I assume may be because scp command not working properly)Here's the code:
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;
Here's the error msg (expect is on debug mode):
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
Any help would be appreciated! Thanks in advance BTW- the problem was annoying enough for me to figure out, as this is my very first post to stack overflow. :)
Try like this:
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
Your interact
may fail because at that time the spawned process may have already exited and obviously it cannot interact with a dead process.
For your script, my expect eof
basically have the same effect with your interact
. They all wait for the spawned process to finish. The difference here is timing. And expect eof
just does not generate error when the spawned process exits.