当在启动时使用expect脚本时,行列表的输出会被缩短。如何在启动时增加期望或终端的缓冲区?

当在启动时使用expect脚本时,行列表的输出会被缩短。如何在启动时增加期望或终端的缓冲区?

我使用通过 autoexpect 生成的以下脚本。当用于命令行时,命令sudo surfshark-vpn multi会给出大约 15 行的列表,然后要求用户以number.

然而,当在启动时使用 Expect 脚本时,这 15 行变成一行,并Enter在每一行之后询问。

我想知道为什么会发生这种情况。不知何故,该命令似乎认为 shell 只有一行。

 $ cat startsurfshark.sh
#!/usr/bin/expect -f
#
# This Expect script was generated by autoexpect on Sat Dec 12 15:36:12 2020

set force_conservative 0  ;# set to 1 to force conservative mode even if
              ;# script wasn't run conservatively originally
if {$force_conservative} {
    set send_slow {1 .1}
    proc send {ignore arg} {
        sleep .1
        exp_send -s -- $arg
    }
}

set timeout -1
log_file /home/USER/startshark.log
spawn $env(SHELL)
match_max 100000
send -- "sudo surfshark-vpn multi\r"
expect -exact "\[sudo\] Passwort for USER: "
send -- "PASSWORD"

expect -exact "press enter for next page"
send -- "\r"

expect -exact "press enter for next page"
send -- "\r"

expect -exact "press enter for next page"
send -- "\r"

expect -exact "press enter for next page"
send -- "\r"

# ... in here should be a lot more 

# ... it then should continou like this

expect -exact "Enter a number to select the location\r"
send -- "2\r"

expect -exact "\r
Enter a number to select the VPN connection type. For default UDP, press ENTER\r
0 TCP\r
1 UDP\r
1 selected\r
"
send -- "\r"
expect -exact "\r
Checking for connection status...\r"
sleep 15
send -- "exit"

请注意,我在以下表单中手动添加了几行。这就是我发现奇怪行为的方式:

expect -exact "press enter for next page"
send -- "\r"

另请注意,该脚本可以使用attack而不是正常工作,multi因为另一个命令不会打印尝试保留在显示器上供用户观看的列表,即使该列表对于显示器大小来说太大。

我的日志文件的输出是:

 $ cat ../startshark.log 
spawn /bin/bash
sudo surfshark-vpn multi
~ - 21:19:10 - ben - [email protected] Mo Dez 14 
 $ sudo surfshark-vpn multi
[sudo] Passwort für ben: 

press enter for next page
0 France Paris
press enter for next page
1 Germany Frankfurt am Main
press enter for next page
2 Hong Kong Hong Kong
press enter for next page
3 India Chennai

当从终端手动运行脚本时(不是在启动时),它将显示如下列表:

0 France Paris
1 Germany Frankfurt am Main
2 Hong Kong Hong Kong
3 India Chennai
4 Netherlands Amsterdam
5 Netherlands Amsterdam
6 Portugal Loule
7 Singapore Singapore
8 Sweden Stockholm
9 United Kingdom Manchester
10 United Kingdom London
11 United States San Francisco
12 United States Dallas
13 United States New York
Enter a number to select the location

我还可以使用 while 循环的形式来按 Enter 键,直到列表结束。我该怎么做呢?

答案1

当您执行spawn ...in操作时expect,它会创建一个 pty 终端,该终端继承程序正在运行的当前 tty 的设置。

因此,当在具有 24 行(例如)的终端中测试脚本时,VPN 程序将看到这一点并进行适当的交互,每 24 行输出提示输入。

例如,如果您现在从 systemd 单元运行脚本,则没有 tty 可以继承设置,并且行数和列数默认为 0。因此 vpn 程序的行为有所不同。

解决方案是在执行之前显式设置所需的行数和列数spawn。这expect是通过在该行之前设置一个变量来完成的spawn ...

set stty_init "rows 24 cols 80"

您甚至可以设置rows 999并避免所有页面提示。

答案2

我不明白启动/非启动差异。

然而,这是循环“按 Enter”业务的方法:

expect {
    -exact "press enter for next page" {
        send -- "\r"
        exp_continue
    }
    -exact "Enter a number to select the location\r"
}
send -- "2\r"

相关内容