1

I have a TCL script that sets a number of variables and reads several files. The last file it reads may contain sensitive information, so I need to make sure this file gets deleted even if an error occurs at the beginning of the script:

#!/usr/bin/expect -f

set timeout 5

set foo [lindex $argv 0]
set bar [lindex $argv 1]
set secret [lindex $argv 2]

if { ! ([file exists "$foo"] && [file executable "$foo"]) } {
    puts stderr "$foo does not exist or is not executable"
    exit 2
}

if { ! ([file exists "$bar"] && [file executable "$bar"]) } {
    puts stderr "$bar does not exist or is not executable"
    exit 3
}

if { ! ([file exists "$secret"] && [file readable "$secret"]) } {
    puts stderr "$secret does not exist or is not readable"
    exit 4
}

#Read secret, do foo, do bar, etc.

file delete $secret

Looking at try I think I can do this:

try {
    set foo [lindex $argv 0]
    set bar [lindex $argv 1]
    set secret [lindex $argv 2]

    if { ! ([file exists "$foo"] && [file executable "$foo"]) } {
        puts stderr "$foo does not exist or is not executable"
        exit 2
    }

    if { ! ([file exists "$bar"] && [file executable "$bar"]) } {
        puts stderr "$bar does not exist or is not executable"
        exit 3
    }

    if { ! ([file exists "$secret"] && [file readable "$secret"]) } {
        puts stderr "$secret does not exist or is not readable"
        exit 4
    }

    #Read the file, do foo, do bar, etc.

    file delete $secret
} on error {
    file delete $secret
    exit
}

But I'm unfamiliar with TCL syntax and having a hard time finding things in the documentation. Will this work, or do I need to change on error to on error {result options}? In that case, what is result and options? Or do I need to use trap instead?

1 Answer 1

3

In Tcl documentation, optional elements look like ?this?: example from http://tcl.tk/man/tcl8.6/TclCmd/try.htm showing the handlers and "finally" clauses are optional:

try body ?handler...? ?finally script?

In the on clause, variableList is not optional, but you can provide an empty list. If you provide {result options}, result is the error message (for humans) and options is a dictionary holding specific information about the error (see the return man page for details).

To reduce code duplication, use the finally block

try {
    # your code here
} on error {} {
    exit
} finally {
    file delete $secret
} 
2
  • 1
    I tried the OP's code with a finally block, and I could not get it to work. Then I changed the exit statements in the try block to error statements, and it worked. Should the OP do that, or is there some way to catch an exit? Aug 28, 2014 at 16:06
  • Good question. @DonalFellows can you help? Aug 28, 2014 at 16:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .