No Such Variable When Using While Loop in Expect

556 Views Asked by At

I'm attempting to access a variable within a while loop in expect, but I keep getting an error that the variable doesn't exist. The code in question:

#!/usr/bin/expect
spawn ./simulator.sh
set timeout 1

...<extra code>...

# Return the time in seconds from epoch
proc getTime {year month day hour minute} {
    set rfc_form ${year}-${month}-${day}T${hour}:${minute}
    set time [clock scan $rfc_form]
    return $time
}

# Get a handle to the file to store the log output
set fileId [open $filename "a"]
# Get one line at a time
expect -re {.*the number of lines from the debug log file to appear on one page.*}
send "1\r"
# Get the initial time stamp and store the first line
expect -re {^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})\..*$} {
    puts -nonewline $fileId $expect_out(0,string)
    set initTime $expect_out(1,string) $expect_out(2,string) $expect_out(3,string) $expect_out(4,string) $expect_out(5,string)
}
send "1\r"
# Iterate over the logs until we get at least 5 minutes worth of log data
while { true } {
    expect -re {^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})\..*$} {
        puts -nonewline $fileId $expect_out(0,string)
        set currentTime $expect_out(1,string) $expect_out(2,string) $expect_out(3,string) $expect_out(4,string) $expect_out(5,string)
    }
    # 300 = 5 minutes * 60 seconds
    if { $initTime - $currentTime > 300 } break
    expect -re {.*enter.*}
    send "n\r"
}

...<extra code>...

And the error I get is:

$ ./test.sh
the number of lines from the debug log file to appear on one page1
201505151624.00 721660706 ns | :OCA (027):MAIN (00) | CONTROL |START LINE
enter1
201505151620.00 022625203 ns | :OCA (027):MAIN (00) | CONTROL |com.citrix.cg.task.handlers.ADDeltaSyncHandler:ThreadID:1182, Delta sync on:activedirectory2
entercan't read "initTime": no such variable
    while executing
"if { $initTime - $currentTime > 300 } break"
    ("while" body line 7)
    invoked from within
"while { true } {
        expect -re {^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})\..*$} {
                puts -nonewline $fileId $expect_out(0,string)
                set currentTime $expect_o..."
    (file "./test.sh" line 42)

I'm sure I'm doing something incredibly stupid, but I can't figure it out for the life of me. Thanks for the help in advance!

1

There are 1 best solutions below

1
On BEST ANSWER

This expect pattern has not matched:

expect -re {^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})\..*$} {
    puts -nonewline $fileId $expect_out(0,string)
    set initTime $expect_out(1,string) $expect_out(2,string) $expect_out(3,string) $expect_out(4,string) $expect_out(5,string)
}

You would know if it did match because you would get a syntax error: the set command takes only one or two arguments, and you have given it 6.

Add exp_internal 1 to a line before the spawn command, and expect will show you verbose debugging to let you know how your patterns are or are not matching.

To solve the set syntax error, you probably want

    set initTime [getTime $expect_out(1,string) $expect_out(2,string) $expect_out(3,string) $expect_out(4,string) $expect_out(5,string)]

Also, in the if condition, be aware that $initTime will be smaller than $currentTime , so {$initTime - $currentTime > 300} will never be true, so your loop will be infinite.