【问题标题】:Can I run jshell inside Unix expect?我可以在 Unix 期望中运行 jshell 吗?
【发布时间】:2018-01-05 01:19:31
【问题描述】:

我想使用 expect 重定向 jshell 输入,这样我就可以在录制的演示中模拟输入。但是,虽然我可以从一个期望脚本生成一个 jshell 进程,它也可以识别 jshell 提示符,但在那之后就没有任何效果了。期望输出看起来像控制序列的东西,比如^[[24;9R,我没有看到来自 jshell 的任何输出。不同的终端类型产生不同的字符序列,但它们都不起作用。这种行为在 Ubuntu 和 Mac OS 上的期望是一致的。欢迎任何有关如何调查此问题的建议。 expect -d 没有帮助。

这是我要模拟的 jshell 会话的记录

$ jshell
|  Welcome to JShell -- Version 9.0.1
|  For an introduction type: /help intro

jshell> 3
$1 ==> 3

jshell> 

这是我认为应该这样做的脚本:

#!/usr/bin/expect -f
spawn jshell
expect jshell>
send "3\r"
expect jshell>

当我运行该脚本(在 Mac OS 10.11.6 上,但在 Ubuntu 上得到非常相似的结果)时,我看到了这个输出

spawn jshell
|  Welcome to JShell -- Version 9.0.1
|  For an introduction type: /help intro

jshell> ^[[24;9R

然后期望超时,并且最后一行输出被 shell 提示符覆盖(因此看起来好像在超时时正在写入更多控制字符)。

-d 添加到脚本第 1 行中的期望标志会产生以下输出:

expect version 5.45
argv[0] = /usr/bin/expect  argv[1] = -d  argv[2] = -f  argv[3] = ./expectscript
set argc 0
set argv0 "./expectscript"
set argv ""
executing commands from command file ./expectscript
spawn jshell
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {19712}

expect: does "" (spawn_id exp8) match glob pattern "jshell>"? no
|  Welcome to JShell -- Version 9.0.1
|  For an introduction type: /help intro

expect: does "|  Welcome to JShell -- Version 9.0.1\r\n|  For an introduction type: /help intro\r\n" (spawn_id exp8) match glob pattern "jshell>"? no

jshell>
expect: does "|  Welcome to JShell -- Version 9.0.1\r\n|  For an introduction type: /help intro\r\n\r\njshell> " (spawn_id exp8) match glob pattern "jshell>"? yes 
expect: set expect_out(0,string) "|  Welcome to JShell -- Version 9.0.1\r\n|  For an introduction type: /help intro\r\n\r\njshell> "
expect: set expect_out(spawn_id) "exp8"
expect: set expect_out(buffer) "|  Welcome to JShell -- Version 9.0.1\r\n|  For an introduction type: /help intro\r\n\r\njshell> "
send: sending "3\r" to { exp8 }

expect: does "" (spawn_id exp8) match glob pattern "jshell>"? no

expect: does "\u001b[6n" (spawn_id exp8) match glob pattern "jshell>"? no
^[[32;1Rexpect: timed out

【问题讨论】:

    标签: terminal expect tty pty jshell


    【解决方案1】:

    设法使其工作(在 Debian 9.3 上使用 jshell 9.0 和 Expect 5.45 测试):

    [STEP 103] # cat jshell.exp
    proc expect_prompt {} {
        upvar spawn_id spawn_id
    
        expect -ex "jshell> "
    
        # the CPR (cursor position report) code
        expect -ex "\x1b\[6n"
    
        # read the CPR result and send it the application
        expect_tty -re {\x1b\[[0-9]+;[0-9]+R}
        send $expect_out(0,string)
    }
    
    stty raw; # give tty's full control to jshell since it's crazy
    
    spawn jshell
    expect_prompt
    
    send "3\r"
    expect_prompt
    
    send "/exit\n"
    expect eof
    [STEP 104] # expect jshell.exp
    spawn jshell
    |  Welcome to JShell -- Version 9.0.1
    |  For an introduction type: /help intro
    
    jshell> 3
    $1 ==> 3
    
    jshell> /exit
    |  Goodbye
    [STEP 105] #
    

    神奇之处在于CPR (cursor position report)(在页面上搜索CPR)。

    1. ^[[6n (^[ == ESC == 0x1b == \u001b) 是 CPR 请求(由 jshell 发送)。
    2. ^[[32;1R(第 32 行,第 1 列)等字符串是当前光标位置(由终端驱动程序生成并由 jshell 回读)。

    【讨论】:

      猜你喜欢
      • 2017-03-28
      • 1970-01-01
      • 2014-05-08
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多