我可以 运行 Unix 中的 jshell expect 吗?
Can I run jshell inside Unix expect?
我想使用 expect 重定向 jshell 输入,这样我就可以在录制的演示中模拟输入。但是,尽管我可以从 expect 脚本中生成一个 jshell 进程,它也可以识别 jshell 提示符,但之后什么都不起作用。 expect 输出看起来像控制序列的东西,比如 ^[[24;9R
,我没有看到 jshell 的任何输出。不同的终端类型产生不同的字符序列,但其中 none 有效。此行为在 Ubuntu 和 Mac OS 上的 expect 之间是一致的。欢迎就如何调查此问题提出任何建议。 expect -d
没有帮助。
这是我要模拟的 jshell 会话的记录
$ jshell
| Welcome to JShell -- Version 9.0.1
| For an introduction type: /help intro
jshell> 3
==> 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
然后 expect 超时,输出的最后一行被 shell 提示符覆盖(因此看起来好像在超时时写入了更多控制字符)。
在脚本第 1 行中将 -d
添加到 expect 的标志中会产生以下输出:
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
设法让它工作(在 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
==> 3
jshell> /exit
| Goodbye
[STEP 105] #
魔术是关于CPR (cursor position report)(在页面上搜索CPR
)。
-
^[[6n
(^[
== ESC == 0x1b
== \u001b
) 是CPR请求(由 jshell
) 发送。
- 像
^[[32;1R
这样的字符串(第32行,第1列)是当前光标位置(由终端驱动程序生成并由jshell
读回)。
我想使用 expect 重定向 jshell 输入,这样我就可以在录制的演示中模拟输入。但是,尽管我可以从 expect 脚本中生成一个 jshell 进程,它也可以识别 jshell 提示符,但之后什么都不起作用。 expect 输出看起来像控制序列的东西,比如 ^[[24;9R
,我没有看到 jshell 的任何输出。不同的终端类型产生不同的字符序列,但其中 none 有效。此行为在 Ubuntu 和 Mac OS 上的 expect 之间是一致的。欢迎就如何调查此问题提出任何建议。 expect -d
没有帮助。
这是我要模拟的 jshell 会话的记录
$ jshell
| Welcome to JShell -- Version 9.0.1
| For an introduction type: /help intro
jshell> 3
==> 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
然后 expect 超时,输出的最后一行被 shell 提示符覆盖(因此看起来好像在超时时写入了更多控制字符)。
在脚本第 1 行中将 -d
添加到 expect 的标志中会产生以下输出:
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
设法让它工作(在 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
==> 3
jshell> /exit
| Goodbye
[STEP 105] #
魔术是关于CPR (cursor position report)(在页面上搜索CPR
)。
-
^[[6n
(^[
== ESC ==0x1b
==\u001b
) 是CPR请求(由jshell
) 发送。 - 像
^[[32;1R
这样的字符串(第32行,第1列)是当前光标位置(由终端驱动程序生成并由jshell
读回)。