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 0at 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.^Dwas ineffective, and you're still expecting eof. Trysend \x04expect -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 { $}expect -regex ".*foo.*\r"matches the "foo" inecho 'foo', so the ^D is being send quite early.exp_internal 1to the top of the script. The output is quite verbose. Look for "does this pattern match this buffer, yes or no"