Reputation: 221
I have a following procedure:
proc myexec { args } {
info_msg "Executing shell command: $args"
set catch_res [catch {eval exec $args} res]
if { $catch_res != 0 } {
error_msg "Failed in command: $args"
error_msg "$res"
}
return $catch_res
}
It only checks Unix commands and doesn't work with Tcl commands. How can I change this procedure so that it will work with Tcl commands?
For example, if I want to check that the following commands evaluate without error:
set object1 $object2
or
open $filename r
Upvotes: 4
Views: 3570
Reputation: 137557
The simplest method is to do this:
proc myeval { args } {
info_msg "Executing Tcl command: $args"
set catch_res [catch $args res]
if { $catch_res != 0 } {
error_msg "Failed in command: $args"
error_msg "$res"
}
return $res
}
Here, we've replaced catch {eval exec $args} res
with catch $args res
(plus some cosmetic stuff) which will cause the arguments to be evaluated as a script without further substitution. You'd use it like this:
myeval foo bar $boo
Alternatively, if you're after doing substitutions within the catch
as well, you'd be better writing this more complex version:
proc myeval { script } {
info_msg "Executing Tcl command: [string trim $script]"
set catch_res [catch [list uplevel 1 $script] res]
if { $catch_res != 0 } {
error_msg "Failed in command: [string trim $script]"
error_msg "$res"
}
return $res
}
In this case, you'd call it like this:
myeval {
foo bar $boo
}
Upvotes: 3
Reputation: 4372
If you just want to modify this procedure so it runs the arguments passed as a Tcl command instead of as a Unix command, just drop the exec, ie. instead of eval exec $args
just do eval $args
.
Making a single procedure handle both Tcl and Unix commands is harder, but Tcl already does this for commands you type in tclsh or wish - it looks for a built-in command first and if it doesn't find one it then tries to run it as a Unix command. You can turn on this behaviour in a script by doing set ::tcl_interactive 1
- more details at Tcl Wiki
Upvotes: 1