Double Buffering

When a spawned process produces a line of output, it does not immediately go into Expect’s buffer. In Chapter 4 (p. 89), I described how the UNIX kernel processes characters in chunks. The kernel, in a sense, contains its own buffer from which it doles out these chunks when expect asks for more.

This kernel buffer is separate from expect’s buffer. The kernel’s buffer is only checked when expect cannot find a match using the data already in its own buffer. This double buffering rarely has any impact on the way scripts behave. However, there are some cases in which the buffering does make a difference. For instance, imagine that you have a shell script named greet that prints hello, sleeps five seconds, and then prints goodbye.

echo hello
exec sleep 5
echo goodbye

Now, consider the following Expect script:

spawn /bin/sh greet
expect "h"
exec sleep 10
expect -re ".*o"

This script finds the h from hello and then sleeps for 10 seconds. During that time, the shell script prints goodbye. This string is handed to the kernel which buffers it until Expect asks for it.

When Expect awakens, expect searches its input buffer for anything with an o at the end. This is satisfied by ello and expect returns. The string goodbye is not tested because it is never read by expect.

A more realistic situation arises when using the simple "*" pattern. This always matches everything in expect’s internal buffer and returns immediately. It never causes expect to ask the kernel for more input, even ...

Get Exploring Expect now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.