I'm working on an automated testing of an interactive script in fsharp
, and I'm using brew's version of expect on a osx system. It works with mono's fsharpi
, but not with dotnet fsi
, and I don't understand the difference. I want to automatize dialogues as
% 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;;
In dotnet fsi
, it looks similar
% 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;;
except colors are added by default, which can be turned off, and does not seem to be the cause of the problem. The fsharp
versions are different, but again, I don't think this is the cause of the problem.
A simplified version of my problem is as follows: My expect script for fsharpi is
#!/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
and for dotnet I spawn dotnet fsi
instead of fsharpi
. I call them testFsharpi.exp
and testDotnet.exp
. When run as
./testFsharpi.exp > testFsharpi.out >& testFsharpi.dbg
The content of testFsharpi.out
is
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
and the content of testFsharpi.dbg
is
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 "
\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\r\nMicrosoft (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 "\r\nMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\r\nMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved." (spawn_id exp6) match glob pattern "> "? no
Copyright (c) Microsoft Corporation. All Rights Reserved.
expect: does "\r\nMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved.\r\n\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\r\nMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved.\r\n\r\nFor help type #help;;\r\n" (spawn_id exp6) match glob pattern "> "? no
For help type #help;;
expect: does "\r\nMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved.\r\n\r\nFor help type #help;;\r\n\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\r\nMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved.\r\n\r\nFor help type #help;;\r\n\r\n> " (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) "\r\nMicrosoft (R) F# Interactive version 11.0.0.0 for F# 5.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved.\r\n\r\nFor help type #help;;\r\n\r\n> "
send: sending "let a = 3;;\n" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n" (spawn_id exp6) match glob pattern "> "? no
let a = 3;;
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=" (spawn_id exp6) match glob pattern "> "? no
[?1h=
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n" (spawn_id exp6) match glob pattern [6n"> "? no
expect: does "[H[2Jlet a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J" (spawn_id exp6) match glob pattern "> "? no
expect: does "[1;1Hlet a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- " (spawn_id exp6) match glob pattern "> "? no
-
expect: does "[1;3Hlet a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "[1;3Hlet a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
[1;3H
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
[1;3H
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
[1;3H[1;3H
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hl" (spawn_id exp6) match glob pattern "> "? no
l
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hle" (spawn_id exp6) match glob pattern "e> "? no
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;" (spawn_id exp6) match glob pattern "> "? no
t a = 3;;
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\n" (spawn_id exp6) match glob pattern "> "?
no
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\nval" (spawn_id exp6) match glob pattern "> "? no
val
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\nval " (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\nval a" (spawn_id exp6) match glob pattern "> "? no
a
expect: does " : int = let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\nval a : int = " (spawn_id exp6) match glob pattern "> "? no
expect: does "3let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\nval a : int = 3" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\nval a : int = 3\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\nval a : int = 3\r\n\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "> let a = 3;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\nval a : int = 3\r\n\r\n> " (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;;\r\n\u001b[?1h\u001b=\u001b[6n\u001b[H\u001b[2J\u001b[1;1H- \u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3H\u001b[1;3Hlet a = 3;;\r\nval a : int = 3\r\n\r\n> "
send: sending "let b = 3*a;;\n" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[4;3H\u001b[4;3H\u001b[4;3H\u001b[4;3H" (spawn_id exp6) match glob pattern "> "? no
[4;3H[4;3H[4;3H[4;3H
expect: does "\u001b[4;3H\u001b[4;3H\u001b[4;3H\u001b[4;3Hl" (spawn_id exp6) match glob pattern "> "? no
l
expect: does "\u001b[4;3H\u001b[4;3H\u001b[4;3H\u001b[4;3Hlet b = 3*a;;" (spawn_id exp6) match glob pattern "> "? no
et b = 3*a;;
expect: does "\u001b[4;3H\u001b[4;3H\u001b[4;3H\u001b[4;3Hlet b = 3*a;;\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "val \u001b[4;3H\u001b[4;3H\u001b[4;3H\u001b[4;3Hlet b = 3*a;;\r\nval " (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[4;3H\u001b[4;3H\u001b[4;3H\u001b[4;3Hlet b = 3*a;;\r\nval b : int = 9" (spawn_id exp6) match glob pattern "> "? no
b : int = 9
expect: does "\u001b[4;3H\u001b[4;3H\u001b[4;3H\u001b[4;3Hlet b = 3*a;;\r\nval b : int = 9\r\n\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[4;3H\u001b[4;3H\u001b[4;3H\u001b[4;3Hlet b = 3*a;;\r\nval b : int = 9\r\n\r\n> " (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;3H\u001b[4;3H\u001b[4;3H\u001b[4;3Hlet b = 3*a;;\r\nval b : int = 9\r\n\r\n> "
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;3H\u001b[7;3H\u001b[7;3H\u001b[7;3H#quit;;\r\n\u001b[?1l\u001b>\u001b[39;49m"
However, when I run testDotnet.exp
it enters into an infinite loop. The first part of the output of the debug file is
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[?1h\u001b=" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[?1h\u001b=\u001b[?1h\u001b=" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[?1h\u001b=\u001b[?1h\u001b=\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[?1h\u001b=\u001b[?1h\u001b=\r\nMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[?1h\u001b=\u001b[?1h\u001b=\r\nMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved.\r\n\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[?1h\u001b=\u001b[?1h\u001b=\r\nMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved.\r\n\r\nFor help type #help;;\r\n\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[?1h\u001b=\u001b[?1h\u001b=\r\nMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved.\r\n\r\nFor help type #help;;\r\n\r\n> " (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[?1h\u001b=\u001b[?1h\u001b=\r\nMicrosoft (R) F# Interactive version 12.0.0.0 for F# 6.0\r\nCopyright (c) Microsoft Corporation. All Rights Reserved.\r\n\r\nFor help type #help;;\r\n\r\n> "
send: sending "let a = 3;;\n" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- " (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- l" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let " (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;\r\n\u001b[39;49m" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;\r\n\u001b[39;49m\u001b[97m" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;\r\n\u001b[39;49m\u001b[97mval\u001b[39;49m" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;\r\n\u001b[39;49m\u001b[97mval\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49ma\u001b[39;49m\u001b[39;49m:\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[96mint\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m=\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[92m3\u001b[39;49m" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;\r\n\u001b[39;49m\u001b[97mval\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49ma\u001b[39;49m\u001b[39;49m:\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[96mint\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m=\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[92m3\u001b[39;49m\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;\r\n\u001b[39;49m\u001b[97mval\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49ma\u001b[39;49m\u001b[39;49m:\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[96mint\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m=\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[92m3\u001b[39;49m\r\n\r\n" (spawn_id exp6) match glob pattern "> "? no
expect: does "let a = 3;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;\r\n\u001b[39;49m\u001b[97mval\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49ma\u001b[39;49m\u001b[39;49m:\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[96mint\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m=\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[92m3\u001b[39;49m\r\n\r\n> " (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;;\r\n\u001b[6n\u001b[6n\u001b[1;1H- let a = 3;;\r\n\u001b[39;49m\u001b[97mval\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49ma\u001b[39;49m\u001b[39;49m:\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[96mint\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m=\u001b[39;49m\u001b[39;49m \u001b[39;49m\u001b[39;49m\u001b[92m3\u001b[39;49m\r\n\r\n> "
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[6n\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\u001b[1;2H" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\u001b[1;2H\u001b[1;3H\ufffd" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\u001b[1;2H\u001b[1;3H\ufffd\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\u001b[1;2H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\u001b[1;2H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
expect: does "\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H\u001b[1;2H\u001b[1;3H\ufffd\u001b[6n- \u001b[6n\u001b[6n\u001b[1;1H\u001b[1;3H?\ufffd\u001b[6n" (spawn_id exp6) match glob pattern "> "? no
^C
I don't understand why it works in one but not the other program. I have tried inserting sleep
s and send_slow
with no effects. Any ideas?
Thanks, Jon
CodePudding user response:
A friend of mine came up with the solution. For dotnet fsi, I must spawn with
spawn dotnet fsi --readline-
For completeness sake, my expect script in the end is
#!/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
Thanks, everybody
CodePudding user response:
(Not a direct answer. Just FYI.)
The sequence \u001b[6n
(ESC [ 6 n
) in the debug output indicates dotnet fsi
is requesting the tty's current cursor position. The ESC [ 6 n
sequence is called CPR (cursor position report).
This is what happens when you manually interact with dotnet fsi
:
- After
dotnet fsi
prints the prompt>
it requests the cursor position by printingESC [ 6 n
to the tty. And then it'll wait for the CPR result. - When the tty receives the CPR request, it'll send the CPR result (
ESC [ row ; col R
) back to the tty's input buffer. - Then
dotnet fsi
gets the CPR result and continue reading user's input.
When Expect is involved, the CPR result is actually got by Expect so Expect should read the CPR result and "forward" it to dotnet fsi
, otherwise dotnet fsi
will keep waiting (not sure if it has a timeout mechanism).
I'll use my sexpect to demo how to make it work --
The script automate-dotnet-fsi.sh
:
wait_prompt()
{
local rep
sexpect expect -re $'[\r\n]> \033\\[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
Result (tested on 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;;