0

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 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

First off, thank you so much for taking the time to respond--this was immensely helpful in seeing that I was way off in left field. The verbose debugging was the key here as it showed that the input I was receiving did NOT start with the digits I expected but rather a new line command, so my match (as you aptly pointed out) did not match. I also updated my set command to be syntactically correct. Lastly, I updated the variable names from initTime and currentTime to startTime and previousTime respectively to make it a little clearer to future devs that the time is in reverse chronological order

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.