Calling an external prog - timeout and error-handling in Expect 
Author Message
 Calling an external prog - timeout and error-handling in Expect

Hi. I've been programming in Tcl and am getting started with the
Expect extension.

I would like to call an external program from my script with specific
arguments read from an input file. The input file is actually made
up of a long list, and the script loops through, calling the program
with successive pair of arguments.

I've written a Tcl version of the script and am porting it to Expect,
and there are 2 key issues I'd like to address regarding different
options
of calling the external program.

#1. I'd like to "catch" any errors from running the program because
the script
moves the output generated to either the "success" or "faults"
directory
based on the result of that run.

#2. I'd like to set a timeout value (ie 180 or 3 minutes), because the
program that's called sometimes hangs, and that process needs to be
killed
so that the script can go on to the next iteration.
-----------------------------------------------------------------------------
Except for this last part, I was able to use Tcl features. Now that
I'm
using Expect, I'm confused between the features of 'send', 'spawn',
and
Tcl's own 'catch' and 'exec'.

The external program I call is saved in the value $patchx.
My original Tcl script did:

catch { exec $patchx -f ${curr_infile} >${curr_outfile} } curr_result
        global errorInfo
        if { [info exists errorInfo] } { set curr_error $errorInfo }
        ... etc...

- this code worked well because the Tcl script would continue to run
the
next iteration without getting interrupted every time the
external-called
program failed. I directed the 'curr_result' output to a logfile, so
I could see which arguments from the input list created errors.

- However, Tcl is not equipped to handle timeouts...
---------------------------------------------------------------------------
To do a timeout, I now followed the advice of the Expect book and
created a separate procedure to call the external program each time.
I would return a value indicating whether the program had timed out or
not
(using a global variable, similar to a #define VALUE in C.

set completed 0
set timed_out 1
...
... other code here ...
...
proc run_patch { exec_cmd } {
    global logid
    global completed
    global timed_out
    global curr_result
    set timeout 300
    puts $logid "Value of exec_cmd inside the proc is: ${exec_cmd}."
    catch { eval $exec_cmd } curr_result
    # Can print out $curr_result if it's useful here.
    # puts $curr_result
    # For debugging
    puts "Inside proc run_patch, executed it with following result:
${curr_result}."

    expect {
        # "Patch ran success" { return $success }
        timeout {
        puts $logid "Command ${exec_cmd} timed out; need to move to timeouts
dir."
        set curr_result 0
        return $timed_out
        }
    }
    return $completed

Quote:
}

...
... other code parsing the input list etc here...
...
if { ![file exists ${curr_outfile}] } {
   set exec_cmd [list {exec} $patchx {-f} $curr_infile {>}
$curr_outfile]
   puts $logid "Calling proc to run following command: $exec_cmd \n"
   set curr_return [run_patch $exec_cmd]
   global errorInfo
   if { [info exists errorInfo] } { set curr_error $errorInfo }
   ...
   ... other code that logs the output, indicating whether the
external patch
   ... prog ran successfully, failed, or timed out...
   ...

There are a couple problems:

1. For some reason, if the called program fails, the script stops. I'm
wondering if it's because
of the way I send the command string to the subroutine 'run_patch'.
Maybe if I do something like:
   eval { $new_exec_cmd }
   - where new_exec_cmd is something like: catch exec $patchx arg1
arg2 ...
Any comments?

2. I haven't had a chance to test the timeout feature because the
script stops running so soon
because of what happens above. However, will the proc run_patch
process the timeout properly?

------------------------------------------------------------------------------------------
As a general Expect question, I would like to know how 'spawn' or
'send' may be
applicable to this problem.

Specifically, it may be good to call the external program using
'spawn', and I think
the timeout-handling would be straightforward.

How would I translate the 'exec' call from Tcl to 'spawn' and handle
the timeout issue?

My concern would then move to error-handling. I don't yet know enough
about Expect to
know how to handle the program's return value and error message if I
called it through
a 'spawn' process.

I know that 'send' basically sends a string to the current open
process, so I can
conceivably call the program using 'send' instead of 'exec' as well,
right?

Does doing so have any advantages? Specifically, is 'send' what is
needed to use 'expect',
or is my use of it in the subroutine okay as it is?

------------------------------------------------------------------------------

Thank you very much!

If you have any suggestions about online Expect tutorials, feel free
to let me know as well.

Best,
Jay Lulla



Wed, 25 May 2005 13:13:22 GMT  
 Calling an external prog - timeout and error-handling in Expect

Quote:

>Hi. I've been programming in Tcl and am getting started with the
>Expect extension.

                        .
                        .
                        .
Quote:
>#2. I'd like to set a timeout value (ie 180 or 3 minutes), because the
>program that's called sometimes hangs, and that process needs to be
>killed
>so that the script can go on to the next iteration.

                        .
                        .
                        .
Quote:
>2. I haven't had a chance to test the timeout feature because the
>script stops running so soon
>because of what happens above. However, will the proc run_patch
>process the timeout properly?

                        .
                        .
                        .
No.  Well, Expect will perform as documented, but it
doesn't do what you think.

You need a more complete explanation, and apparently
no one's going to have time to supply it until late
Monday night at the earliest.  My advice is to read
more of the Expect book, and/or work on other projects,
until we can get back to you.
--


Business:  http://www.Phaseit.net
Personal:  http://phaseit.net/claird/home.html



Fri, 27 May 2005 22:37:56 GMT  
 Calling an external prog - timeout and error-handling in Expect

Quote:

> Hi. I've been programming in Tcl and am getting started with the
> Expect extension.

> I would like to call an external program from my script with specific
> arguments read from an input file. The input file is actually made
> up of a long list, and the script loops through, calling the program
> with successive pair of arguments.

> I've written a Tcl version of the script and am porting it to Expect,
> and there are 2 key issues I'd like to address regarding different
> options
> of calling the external program.

> #1. I'd like to "catch" any errors from running the program because
> the script
> moves the output generated to either the "success" or "faults"
> directory
> based on the result of that run.

> #2. I'd like to set a timeout value (ie 180 or 3 minutes), because the
> program that's called sometimes hangs, and that process needs to be
> killed
> so that the script can go on to the next iteration.
> -----------------------------------------------------------------------------
> Except for this last part, I was able to use Tcl features. Now that
> I'm
> using Expect, I'm confused between the features of 'send', 'spawn',
> and
> Tcl's own 'catch' and 'exec'.

> The external program I call is saved in the value $patchx.
> My original Tcl script did:

> catch { exec $patchx -f ${curr_infile} >${curr_outfile} } curr_result
>    global errorInfo
>    if { [info exists errorInfo] } { set curr_error $errorInfo }
>    ... etc...

> - this code worked well because the Tcl script would continue to run
> the
> next iteration without getting interrupted every time the
> external-called
> program failed. I directed the 'curr_result' output to a logfile, so
> I could see which arguments from the input list created errors.

> - However, Tcl is not equipped to handle timeouts...
> ---------------------------------------------------------------------------
> To do a timeout, I now followed the advice of the Expect book and
> created a separate procedure to call the external program each time.
> I would return a value indicating whether the program had timed out or
> not
> (using a global variable, similar to a #define VALUE in C.

> set completed 0
> set timed_out 1
> ...
> ... other code here ...
> ...
> proc run_patch { exec_cmd } {
>     global logid
>     global completed
>     global timed_out
>     global curr_result
>     set timeout 300
>     puts $logid "Value of exec_cmd inside the proc is: ${exec_cmd}."
>     catch { eval $exec_cmd } curr_result
>     # Can print out $curr_result if it's useful here.
>     # puts $curr_result
>     # For debugging
>     puts "Inside proc run_patch, executed it with following result:
> ${curr_result}."

>     expect {
>    # "Patch ran success" { return $success }
>    timeout {
>    puts $logid "Command ${exec_cmd} timed out; need to move to timeouts
> dir."
>    set curr_result 0
>    return $timed_out
>    }
>     }
>     return $completed
> }
> ...
> ... other code parsing the input list etc here...
> ...
> if { ![file exists ${curr_outfile}] } {
>    set exec_cmd [list {exec} $patchx {-f} $curr_infile {>}
> $curr_outfile]
>    puts $logid "Calling proc to run following command: $exec_cmd \n"
>    set curr_return [run_patch $exec_cmd]
>    global errorInfo
>    if { [info exists errorInfo] } { set curr_error $errorInfo }
>    ...
>    ... other code that logs the output, indicating whether the
> external patch
>    ... prog ran successfully, failed, or timed out...
>    ...

> There are a couple problems:

> 1. For some reason, if the called program fails, the script stops. I'm
> wondering if it's because
> of the way I send the command string to the subroutine 'run_patch'.
> Maybe if I do something like:
>    eval { $new_exec_cmd }
>    - where new_exec_cmd is something like: catch exec $patchx arg1
> arg2 ...
> Any comments?

> 2. I haven't had a chance to test the timeout feature because the
> script stops running so soon
> because of what happens above. However, will the proc run_patch
> process the timeout properly?

> ------------------------------------------------------------------------------------------
> As a general Expect question, I would like to know how 'spawn' or
> 'send' may be
> applicable to this problem.

> Specifically, it may be good to call the external program using
> 'spawn', and I think
> the timeout-handling would be straightforward.

> How would I translate the 'exec' call from Tcl to 'spawn' and handle
> the timeout issue?

> My concern would then move to error-handling. I don't yet know enough
> about Expect to
> know how to handle the program's return value and error message if I
> called it through
> a 'spawn' process.

> I know that 'send' basically sends a string to the current open
> process, so I can
> conceivably call the program using 'send' instead of 'exec' as well,
> right?

> Does doing so have any advantages? Specifically, is 'send' what is
> needed to use 'expect',
> or is my use of it in the subroutine okay as it is?

> ------------------------------------------------------------------------------

> Thank you very much!

> If you have any suggestions about online Expect tutorials, feel free
> to let me know as well.

> Best,
> Jay Lulla


Your script doesn't appear to be using spawn to invoke your program so
send isn't going to work.  send only works with spawned programs.
However, you appear to be redirecting the output in your exec command
so it's not clear to me how you expect to check for a timeout in that
case.

Don



Sat, 28 May 2005 09:13:42 GMT  
 Calling an external prog - timeout and error-handling in Expect

Quote:

>Hi. I've been programming in Tcl and am getting started with the
>Expect extension.

>I would like to call an external program from my script with specific
>arguments read from an input file. The input file is actually made

                        .
                        .
                        .
Quote:
>#2. I'd like to set a timeout value (ie 180 or 3 minutes), because the
>program that's called sometimes hangs, and that process needs to be
>killed
>so that the script can go on to the next iteration.
>-----------------------------------------------------------------------------
>Except for this last part, I was able to use Tcl features. Now that
>I'm
>using Expect, I'm confused between the features of 'send', 'spawn',
>and
>Tcl's own 'catch' and 'exec'.

                        .
                        .
                        .
In the absence of leisure to compose a coherent and accurate
response, I'll wave my hands a bit and wish you well.

First approximation:
  spawn $your_executable $arg1 $arg2 ...
  expect {
      timeout {
          # Do something with result.
      }
  }
The expect_out associative array holds the results you're after.

Next:  "expect eof" ...

Eventually you might have reason to read up on expect_background.
--


Business:  http://www.Phaseit.net
Personal:  http://phaseit.net/claird/home.html



Sat, 28 May 2005 22:24:11 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. expect + timeout handling

2. Expect: timeout & -o timeout

3. error handling using CALL on error name ErrorRtn

4. Handling external errors in Rexx?

5. Handling external errors in Rexx?

6. Handling external errors

7. Handling external errors in Rexx?

8. Expect: changing timeout value within expect?

9. Error calling CICS assembler program to a COBOL II prog

10. Expect Telnet Error Handle?

11. handling errors in expect

12. expect script and error handling

 

 
Powered by phpBB® Forum Software