I am running zsh
inside of tmux
with prezto, and a basic expect script is exiting improperly:
set timeout -1
spawn $env(SHELL)
expect -regex ".*"
send "echo 'foo'\r"
expect -regex ".*foo.*\r"
send "^D"
expect eof
What happens is the foo
is output and expected, the script exits... but the prompt exposed afterwards is broken until I press CTRL-C
on the keyboard. At that point, a %
is printed and the next line appears:
❯ ./modified-autoexpect-recording.exp
spawn /bin/zsh
echo 'foo'
❯ echo 'foo'
foo
~/ < ... fancy stuff ... ❯ ^C% # this was a manual CTRL-C event from a broken prompt
~/ < ... fancy stuff ... ❯ # this is working
A straight autoexpect result produces the same problem. One of the things I noticed is:
~/long/path/here ❯ ^C%
~/lo/pa/here ❯ # after exiting the frozen prompt
An end to end AutoExpect example:
$: autoexpect
$: echo 'foo'
foo
$:[CTRL-D]
$: ./script.exp
$:[CTRL-C]%
$: # prompt works
Behavior remains constant across the following modifications:
# changes at beginning
set log_user 0
set stty sane
changes at end
send -- '^D' # -> send -- \x04
It definitely has something to do with the custom prompt's path getting abbreviated.
I am happy to change my prompt system, but ideally expect just works w/ some mods.
I am reviewing Don's book (O'Reilly), so maybe the answer is there. In the meantime, are there any tricks to have an expect program exit robustly?
log_user 0
at the start of the expect script to stop it copying data it read from the child to the terminal you are in, as it may include some escape sequences. – meuh Mar 03 '23 at 17:04$ stty -echo
. You can undo that with$ stty sane
. – J_H Mar 03 '23 at 17:49^D
was ineffective, and you're still expecting eof. Trysend \x04
– glenn jackman Mar 03 '23 at 18:45expect -regex ".*"
is extremely permissive. It is expecting to see zero or more of any characters. You might want to match your prompt more preciselyexpect -re { $}
– glenn jackman Mar 03 '23 at 18:48expect -regex ".*foo.*\r"
matches the "foo" inecho 'foo'
, so the ^D is being send quite early. – glenn jackman Mar 03 '23 at 18:49autoexpect
result from the^D
– Chris Mar 03 '23 at 18:50exp_internal 1
to the top of the script. The output is quite verbose. Look for "does this pattern match this buffer, yes or no" – glenn jackman Mar 04 '23 at 16:43