1

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?

9
  • Try 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. Commented Mar 3, 2023 at 17:04
  • 2
    I assume the ^D was ineffective, and you're still expecting eof. Try send \x04 Commented Mar 3, 2023 at 18:45
  • 1
    Also expect -regex ".*" is extremely permissive. It is expecting to see zero or more of any characters. You might want to match your prompt more precisely expect -re { $} Commented Mar 3, 2023 at 18:48
  • 1
    Similarly expect -regex ".*foo.*\r" matches the "foo" in echo 'foo', so the ^D is being send quite early. Commented Mar 3, 2023 at 18:49
  • 1
    Your next step: run with internal tracing on. You have an infinite timeout, and the program is hanging, so there must be a pattern that is not matching. Add exp_internal 1 to the top of the script. The output is quite verbose. Look for "does this pattern match this buffer, yes or no" Commented Mar 4, 2023 at 16:43

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.