return = fail
return
didn't work for me because in my case, it was not a shell that can simply prompt me again with the same question. I couldn't figure out how to get it to match on what was printed before I did return
.
expect_out (to fix above solution) = fail
The manual says:
Upon matching a pattern (or eof or full_buffer), any matching and previously unmatched output is saved in the variable expect_out(buffer).
But I couldn't get that to work (except where I used it below, combined with -indices
which makes it work there, and no idea how to make it work to get previous output fed into a new expect { ... }
block.)
expect_user
And the solution here using expect_user
didn't work for me either because it had no explanation and wasn't used how I wanted, so didn't know how to apply this limited example in my actual expect file.
my solution
So what I did instead was avoid the interactive mode, and just have a way to provide input, one line at a time. It even works for arrow keys and alt+...
, (in dpkg Dialog questions) but not for simply <enter>
sometimes (hit alt+y for <Yes>
or alt+o for <Ok>
for those in dpkg Dialog). (anyone know how to send an enter? not '\n', but the enter key like dpkg Dialog wants?)
The -i $user_spawn_id
part means that instead of only looking at your spawned process, it also looks at what the user types. This affects everything after it, so you use expect_after
or put it below the rest, not expect_before
. -indices
makes it possible to read the captured part of the regular expression that matches. expect_out(1,string)
is the part I wanted (all except the colon).
expect_after {
-i $user_spawn_id
# single line custom input; prefix with : and the rest is sent to the application
-indices -re ":(.*)" {
send "$expect_out(1,string)"
}
}
Using expect_after
means it will apply to all following expect
blocks until the next expect_after
. So you can put that anywhere above your usual expect
lines in the file.
and my case/purpose
I wanted to automate do-release-upgrade which does not properly support the usual Debian non-interactive flags (see here)...it just hangs and ignores input instead of proceeding after a question. But the questions are unpredictable... and an aborted upgrade means you could mess up your system, so some fallback to interaction is required.