使用"期望"自动测试交互式 dotnet 程序时遇到问题



我正在fsharp中对交互式脚本进行自动测试,并且我在osx系统上使用brew的expect版本。它适用于单声道的fsharpi,但不适用于dotnet fsi,我不明白其中的区别。我想将对话自动化为

% fsharpi                                            
Microsoft (R) F# Interactive version 11.0.0.0 for F# 5.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> let a = 3;;
val a : int = 3
> let b = 3*a;;
val b : int = 9
> #quit;;

dotnet fsi,它看起来很相似

% dotnet fsi
Microsoft (R) F# Interactive version 12.0.0.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> let a = 3;;
val a: int = 3
> let b = 3*a;;
val b: int = 9
> #quit;;

除了默认情况下添加的颜色,可以关闭,并且似乎不是问题的原因。fsharp版本不同,但同样,我认为这不是问题的原因。

我的问题的简化版本如下:我对 fsharpi 的期望脚本是

#!/usr/bin/expect -df
set timeout -1
# Start fsharp - for some reason, this does not work with dotnet fsi
spawn fsharpi
expect "> "
send -- "let a = 3;;n"
expect "> "
send -- "let b = 3*a;;n"
expect "> "
send -- "#quit;;n"
expect eof

对于 dotnet,我spawn dotnet fsi而不是fsharpi.我称他们为testFsharpi.exptestDotnet.exp.运行时为

./testFsharpi.exp > testFsharpi.out >& testFsharpi.dbg  

testFsharpi.out的内容是

spawn fsharpi
Microsoft (R) F# Interactive version 11.0.0.0 for F# 5.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> let a = 3;;
[?1h=[6n[H[2J[1;1H- [1;3H[1;3H[1;3H[1;3H[1;3H[1;3Hlet a = 3;;
val a : int = 3
> [4;3H[4;3H[4;3H[4;3Hlet b = 3*a;;
val b : int = 9
> [7;3H[7;3H[7;3H[7;3H#quit;;
[?1l>[39;49m

testFsharpi.dbg的内容是

expect version 5.45
argv[0] = /usr/bin/expect  argv[1] = -df  argv[2] = ./testFsharpi.exp  
set argc 0
set argv0 "./testFsharpi.exp"
set argv ""
executing commands from command file ./testFsharpi.exp
spawn fsharpi
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {72534}
expect: does "" (spawn_id exp6) match glob pattern "> "? no
expect: does "
rn" (spawn_id exp6) match glob pattern "> "? no
expect: does "rnMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0" (spawn_id exp6) match glob pattern "> "? Microsoft (R) F# Interactive version 11.0.0.0 for F# 5.0no
expect: does "rnMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0rn" (spawn_id exp6) match glob pattern "> "? no

expect: does "rnMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0rnCopyright (c) Microsoft Corporation. All Rights Reserved." (spawn_id exp6) match glob pattern "> "? no
Copyright (c) Microsoft Corporation. All Rights Reserved.
expect: does "rnMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0rnCopyright (c) Microsoft Corporation. All Rights Reserved.rnrn" (spawn_id exp6) match glob pattern "> "? no

expect: does "rnMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0rnCopyright (c) Microsoft Corporation. All Rights Reserved.rnrnFor help type #help;;rn" (spawn_id exp6) match glob pattern "> "? no
For help type #help;;
expect: does "rnMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0rnCopyright (c) Microsoft Corporation. All Rights Reserved.rnrnFor help type #help;;rnrn" (spawn_id exp6) match glob pattern "> "? no

expect: does "rnMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0rnCopyright (c) Microsoft Corporation. All Rights Reserved.rnrnFor help type #help;;rnrn> " (spawn_id exp6) match glob pattern "> "? yes
expect: set expect_out(0,string) "> "
> expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "rnMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0rnCopyright (c) Microsoft Corporation. All Rights Reserved.rnrnFor help type #help;;rnrn> "
send: sending "let a = 3;;n" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rn" (spawn_id exp6) match glob pattern "> "? no
let a = 3;;
expect: does "let a = 3;;rnu001b[?1hu001b=" (spawn_id exp6) match glob pattern "> "? no
[?1h=
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6n" (spawn_id exp6) match glob pattern [6n"> "? no
expect: does "[H[2Jlet a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2J" (spawn_id exp6) match glob pattern "> "? no
expect: does "[1;1Hlet a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- " (spawn_id exp6) match glob pattern "> "? no
- 
expect: does "[1;3Hlet a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "[1;3Hlet a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
[1;3H
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
[1;3H
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
[1;3H[1;3H
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hl" (spawn_id exp6) match glob pattern "> "? no
l
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hle" (spawn_id exp6) match glob pattern "e> "? no
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;" (spawn_id exp6) match glob pattern "> "? no
t a = 3;;
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rn" (spawn_id exp6) match glob pattern "> "? 
no
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rnval" (spawn_id exp6) match glob pattern "> "? no
val
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rnval " (spawn_id exp6) match glob pattern "> "? no

expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rnval a" (spawn_id exp6) match glob pattern "> "? no
a
expect: does " : int = let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rnval a : int = " (spawn_id exp6) match glob pattern "> "? no
expect: does "3let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rnval a : int = 3" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rnval a : int = 3rn" (spawn_id exp6) match glob pattern "> "? no

expect: does "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rnval a : int = 3rnrn" (spawn_id exp6) match glob pattern "> "? no

expect: does "> let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rnval a : int = 3rnrn> " (spawn_id exp6) match glob pattern "> "? yes
expect: set expect_out(0,string) "> "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "let a = 3;;rnu001b[?1hu001b=u001b[6nu001b[Hu001b[2Ju001b[1;1H- u001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hu001b[1;3Hlet a = 3;;rnval a : int = 3rnrn> "
send: sending "let b = 3*a;;n" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[4;3Hu001b[4;3Hu001b[4;3Hu001b[4;3H" (spawn_id exp6) match glob pattern "> "? no
[4;3H[4;3H[4;3H[4;3H
expect: does "u001b[4;3Hu001b[4;3Hu001b[4;3Hu001b[4;3Hl" (spawn_id exp6) match glob pattern "> "? no
l
expect: does "u001b[4;3Hu001b[4;3Hu001b[4;3Hu001b[4;3Hlet b = 3*a;;" (spawn_id exp6) match glob pattern "> "? no
et b = 3*a;;
expect: does "u001b[4;3Hu001b[4;3Hu001b[4;3Hu001b[4;3Hlet b = 3*a;;rn" (spawn_id exp6) match glob pattern "> "? no

expect: does "val u001b[4;3Hu001b[4;3Hu001b[4;3Hu001b[4;3Hlet b = 3*a;;rnval " (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[4;3Hu001b[4;3Hu001b[4;3Hu001b[4;3Hlet b = 3*a;;rnval b : int = 9" (spawn_id exp6) match glob pattern "> "? no
b : int = 9
expect: does "u001b[4;3Hu001b[4;3Hu001b[4;3Hu001b[4;3Hlet b = 3*a;;rnval b : int = 9rnrn" (spawn_id exp6) match glob pattern "> "? no

expect: does "u001b[4;3Hu001b[4;3Hu001b[4;3Hu001b[4;3Hlet b = 3*a;;rnval b : int = 9rnrn> " (spawn_id exp6) match glob pattern "> "? yes
expect: set expect_out(0,string) "> "
> expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "u001b[4;3Hu001b[4;3Hu001b[4;3Hu001b[4;3Hlet b = 3*a;;rnval b : int = 9rnrn> "
send: sending "#quit;;n" to { exp6 }
[7;3H[7;3H[7;3H[7;3H#quit;;
[?1l>[39;49mexpect: read eof
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "u001b[7;3Hu001b[7;3Hu001b[7;3Hu001b[7;3H#quit;;rnu001b[?1lu001b>u001b[39;49m"

但是,当我运行testDotnet.exp时,它会进入无限循环。调试文件输出的第一部分是

expect version 5.45
argv[0] = /usr/bin/expect  argv[1] = -df  argv[2] = ./testDotnet.exp  
set argc 0
set argv0 "./testDotnet.exp"
set argv ""
executing commands from command file ./testDotnet.exp
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {72656}
expect: does "" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[?1hu001b=" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[?1hu001b=u001b[?1hu001b=" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[?1hu001b=u001b[?1hu001b=rn" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[?1hu001b=u001b[?1hu001b=rnMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0rn" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[?1hu001b=u001b[?1hu001b=rnMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0rnCopyright (c) Microsoft Corporation. All Rights Reserved.rnrn" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[?1hu001b=u001b[?1hu001b=rnMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0rnCopyright (c) Microsoft Corporation. All Rights Reserved.rnrnFor help type #help;;rnrn" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[?1hu001b=u001b[?1hu001b=rnMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0rnCopyright (c) Microsoft Corporation. All Rights Reserved.rnrnFor help type #help;;rnrn> " (spawn_id exp6) match glob pattern "> "? yes
expect: set expect_out(0,string) "> "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "u001b[?1hu001b=u001b[?1hu001b=rnMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0rnCopyright (c) Microsoft Corporation. All Rights Reserved.rnrnFor help type #help;;rnrn> "
send: sending "let a = 3;;n" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rn" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- " (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- l" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let " (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;rn" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;rnu001b[39;49m" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;rnu001b[39;49mu001b[97m" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;rnu001b[39;49mu001b[97mvalu001b[39;49m" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;rnu001b[39;49mu001b[97mvalu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mau001b[39;49mu001b[39;49m:u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[96mintu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49m=u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[92m3u001b[39;49m" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;rnu001b[39;49mu001b[97mvalu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mau001b[39;49mu001b[39;49m:u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[96mintu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49m=u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[92m3u001b[39;49mrn" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;rnu001b[39;49mu001b[97mvalu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mau001b[39;49mu001b[39;49m:u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[96mintu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49m=u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[92m3u001b[39;49mrnrn" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;rnu001b[39;49mu001b[97mvalu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mau001b[39;49mu001b[39;49m:u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[96mintu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49m=u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[92m3u001b[39;49mrnrn> " (spawn_id exp6) match glob pattern "> "? yes
expect: set expect_out(0,string) "> "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "let a = 3;;rnu001b[6nu001b[6nu001b[1;1H- let a = 3;;rnu001b[39;49mu001b[97mvalu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mau001b[39;49mu001b[39;49m:u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[96mintu001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49m=u001b[39;49mu001b[39;49m u001b[39;49mu001b[39;49mu001b[92m3u001b[39;49mrnrn> "
send: sending "let b = 3*a;;n" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hu001b[1;2H" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hu001b[1;2Hu001b[1;3Hufffd" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hu001b[1;2Hu001b[1;3Hufffdu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hu001b[1;2Hu001b[1;3Hufffdu001b[6n- u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hu001b[1;2Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "u001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3Hu001b[1;2Hu001b[1;3Hufffdu001b[6n- u001b[6nu001b[6nu001b[1;1Hu001b[1;3H?ufffdu001b[6n" (spawn_id exp6) match glob pattern "> "? no
^C

我不明白为什么它在一个程序中有效,而在另一个程序中不起作用。我尝试插入sleeps 和send_slow没有任何效果。有什么想法吗?

谢谢,乔恩

(不是直接答案。仅供参考。

调试输出中的序列u001b[6n(ESC [ 6 n) 表示dotnet fsi正在请求 tty 的当前光标位置。ESC [ 6 n序列称为CPR(光标位置报告)。

当您手动与dotnet fsi交互时,就会发生这种情况:

  1. dotnet fsi打印提示后>它通过向 tty 打印ESC [ 6 n来请求光标位置。然后它将等待心肺复苏术结果。
  2. 当 tty 收到心肺复苏术请求时,它会将心肺复苏术结果 (ESC [ row ; col R) 发送回 tty 的输入缓冲区。
  3. 然后dotnet fsi获得心肺复苏术结果并继续阅读用户的输入。

当涉及 Expect 时,CPR 结果实际上是由 Expect 获得的,因此 Expect 应该读取 CPR 结果并将其"转发"给dotnet fsi,否则dotnet fsi将继续等待(不确定它是否有超时机制)。


我将用我的 sexpect 演示如何使其工作 --

脚本automate-dotnet-fsi.sh

wait_prompt()
{
local rep
sexpect expect -re $'[rn]> 33\[6n'
#                            ^^^^^^^^^
# ESC [ row ; col R
read -r -d R rep
# forward CPR to the spawned process
sexpect send "${rep}R"
}
trap 'stty echo' EXIT
stty -echo
export SEXPECT_SOCKFILE=/tmp/dotnet-fsi-$$.sock
sexpect spawn dotnet fsi
wait_prompt
sexpect send -cr 'let a = 3;;'
wait_prompt
sexpect send -cr '#quit;;'
sexpect wait

在 macOS 上测试:

$ bash automate-dotnet-fsi.sh
Microsoft (R) F# Interactive version 12.0.4.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
> let a = 3;;
val a: int = 3
> #quit;;

我的一个朋友想出了解决方案。对于 dotnet fsi,我必须生成

spawn dotnet fsi --readline-

为了完整起见,我最终的期望脚本是

#!/usr/bin/expect -df
set timeout -1
# Start the fsharp interpreter
spawn dotnet fsi --readline- --consolecolors-
expect "> "
# enter commands and exit
send -- "let a = 3;;n"
expect "> "
send -- "let b = 3*a;;n"
expect "> "
send -- "#quit;;n"
expect eof

谢谢大家

最新更新