Search code examples
stringtclexpect

Expect/Tcl: 'string map' removing content in string?


SETUP: Expect/Tcl Script in Linux

USE CASE:

Using expect to wait for the report of some status to be used in a $user_command.

expect  -re "notify (.+)\n"  
set     status $expect_out(1,string)
send   [string map [list SESSION "$status"] "$user_command"]

So when the application sends "notify running", then status is set to running. For that a keyword STATUS in $user_command needs to be replaced with $status, such that, for example

"log STATUS to file"

becomes

"log running to file"

To see what is happing, I wrote

expect_tty  -re "(.+)\n"  
set         status $expect_out(1,string)
send_user   [string map [list SESSION "$status"] "$user_command"]

which works fine when running isolatedly. The output is

log someUserInput to file 

when typing someUserInput to responde to expect_tty. However, as part of a larger script, the string map command it removes anything before the string replacement, so that the output becomes

" to file" 

(without a newline) I checked for the uniqueness of variables in the script, so that this is not an issue.

QUESTION:

What is going on here? How can I make the script robust?


Solution

  • Thanks to @glennjackman:

    The problem is due to applications reporting newline as \r\n, so that (.*)\n in

    expect_tty  -re "(.+)\n" 
    

    matches in expression 1 (the thing inside the brackets) something that includes \r at the end. With \r removing anything before it, string map seems to cut anything before the replaced string. The solution is to expect something that excludes \r, i.e.

    expect -re ``(\[^\r\n\]+)``
    

    which collects anything until end of line, whatsoever the format may be.