期望:match_max 设置缓冲区大小不正确

expect: match_max setting buffer size incorrectly

根据 expect 手册页,

match_max
      defines the size of the buffer (in bytes) used internally by expect.

但是,当我用值 1 调用 match_max 时,expect 在内部一次处理四个字符。 (这可以在 exp_internal 1 生成的输出中看到。)将 match_max 设置为 2 使得 expect 使用 7 个字节的缓冲区,3 定义了 10 个字节的缓冲区字符,4 导致 13,5 导致 16。

为什么会这样?

编辑 - 回答评论中的问题:

手动启动 telnet 会话会得到以下输出:

Trying 192.168.xxx.yyy...
Connected to 192.168.xxx.yyy.
Escape character is '^]'.

运行 telnet expectmatch_max 设置为 1:

expect: does "Tryi" (spawn_id exp11) match glob pattern "Login: $"? no
"Password: $"? no
...
expect: does "ryin" (spawn_id exp11) match glob pattern "Login: $"? no
"Password: $"? no

一次考虑四个字符。

match_max 2做同样的事情:

expect: does "Trying " (spawn_id exp11) match glob pattern "Login: $"? no
"Password: $"? no 
...
expect: does "ying 19" (spawn_id exp11) match glob pattern "Login: $"? no
"Password: $"? no

缓冲区实际设置为七个字符。

我刚刚做了一个测试。对于小数(大约小于 170),match_max N 实际上意味着 3N + 1。对于大数字,N 意味着 2N 多一点。似乎 expect 使用了一个非常有趣的算法。 :)

$ cat foo.exp
log_user 0
spawn yes hello world
match_max [lindex $argv 0]
set n 0
expect {
    full_buffer {
        send_user "forgotten: [string length $expect_out(buffer)]\n"
        if { [incr n] < 5 } {
            exp_continue
        }
    }
}
$ expect foo.exp 1
forgotten: 4
forgotten: 4
forgotten: 4
forgotten: 4
forgotten: 4
$ expect foo.exp 10
forgotten: 31
forgotten: 31
forgotten: 31
forgotten: 31
forgotten: 31
$ expect foo.exp 100
forgotten: 206
forgotten: 301
forgotten: 301
forgotten: 301
forgotten: 301
$ expect foo.exp 1000
forgotten: 2085
forgotten: 2075
forgotten: 2085
forgotten: 2106
forgotten: 2099
$ expect foo.exp 10000
forgotten: 20220
forgotten: 20169
forgotten: 20436
forgotten: 20566
forgotten: 20326
$ expect foo.exp 100000
forgotten: 200133
forgotten: 200161
forgotten: 200408
forgotten: 200090
forgotten: 200440
$

更新:

仅在 expect 的源代码 (exp_clib.c) 中找到:

/* get the latest buffer size.  Double the user input for two */
/* reasons.  1) Need twice the space in case the match */
/* straddles two bufferfuls, 2) easier to hack the division by */
/* two when shifting the buffers later on */

bufsiz = 2*exp_match_max;