SIMEL
SIMEL

Reputation: 8939

What will the following tcl code do?

I have the following line:

if {[catch {exec fgrep E- $log_file} errors]} {
    set errors ""
}

What does this do?

Upvotes: 2

Views: 109

Answers (2)

TrojanName
TrojanName

Reputation: 5375

Yes, you're right. If the command exec fgrep E- $log_file returns any errors, they will be caught and the variable errors will be assigned the error message. In this case it is the results of the exec command that is being caught. Looking at the manual you can see the particularities of how exec returns an error. Your code example immediately over-writes the errors variable. I should add that errors is a slightly misleading choice of variable name - results would be better, as the variable gets set whether or not an error occurs.

So the if will be taken if the catch finds an error. I couldn't comment on the question regarding fgrep not finding a file. It's not clear to me if that is an error or a normal situation.

Upvotes: 1

Donal Fellows
Donal Fellows

Reputation: 137767

Let's deconstruct your code from the inside out.

exec fgrep E- $log_file

This runs fgrep E- against the file whose name is stored in the variable log_file. It produces a Tcl error if there is a syntactic problem with the exec (there isn't, thankfully), a syntactic problem with the fgrep program (looks OK to me), if $log_file doesn't exist, or if there were no matches. If there were no errors, it returns the output of the grepping, warts and all.

catch {exec fgrep E- $log_file} errors

This runs the code from above in an environment which traps errors, and returns whether an error occurred (formally, it returns 0 when there was no error, 1 when there was an error, and other codes for other less-common types of exceptional return which don't happen in this case). The normal result of the exec is stored in the errors variable if no error happened, and the error message is stored in errors if there was an error. Note that it's possible to distinguish between the types of errors through the global errorCode variable, but you don't do that (and it's often not necessary).

if {[catch {exec fgrep E- $log_file} errors]} {
    set errors ""
}

This uses the result of the catch above as a boolean: if an error happened, it evaluates the body (which sets the errors variable to the empty string), and otherwise it does nothing extra.

Summary

Overall, your code sets errors to the newline-separated lines found in the file in log_file, and sets errors to the empty string otherwise.

Upvotes: 4

Related Questions