7

I've been working with TCL for some time now, and I have spent a long time trying to do the following (it seems easy and I think it should be, but I can't get it right):

I need to execute an external program by means of a tcl script. For that, I use the exec command. For using this external program, I need to input a variable amount of files. If I called this program straight from a cmd window, it would be something like:

C:\>myprogram -i file1 -i file2 -i file3 (etc., etc.)

However, when trying to implement this in a dynamic/variable way through tcl I get into trouble. The way I do it is by storing in some variable myvar all the "-i filex" I need (done in a loop), and then pass that as a parameter to the exec command. It would look something like:

exec myprogram $myvar

Doing that apparently creates some issues, because this myprogram fails to "see" myvar. I'm guessing that there is some sort of hidden terminator or some clash of different types of arguments that makes that in the end the exec command "sees" only myprogram.

So, my question is, does anyone know how to insert variable arguments into a call to exec?

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
JasonBourne
  • 165
  • 1
  • 3
  • 14

2 Answers2

9

You can use {*} or eval. See this question for example.

Community
  • 1
  • 1
TrojanName
  • 4,853
  • 5
  • 29
  • 41
  • Thanks for the suggestion. It turns out that with some editting, eval seems to do the trick. Using {*} was not possible because I'm using TCL 8.3, which apparently doesn't accept this command yet. – JasonBourne Dec 16 '11 at 15:35
  • 1
    If you need to support Tcl < 8.5 or just dislike `{*}` (as I do, for instance), be sure to read the chapter on `eval` and quoting from the "Practical programming in Tcl and Tk" book: http://beedub.com/book/3rd/Eval.pdf – kostix Dec 16 '11 at 16:24
6

Specializing for your case:

Tcl 8.5 (and later):

exec myprogram {*}$myvar

Tcl 8.4 (and before):

eval [list exec myprogram] [lrange $myvar 0 end]
# Or...
eval [linsert $myvar 0 exec myprogram]

That's right, the old version is ugly (or non-obvious, or both). Because of that, people tended to write this instead:

eval exec myprogram $myvar

but that was slower than expected (OK, not so relevant when running an external program!) and has hazards when $myvar isn't a canonically-formatted list due to the way that eval works. It used to catch out even experienced Tcl programmers, and that's why we introduced new syntax in 8.5, which is specified to be surprise-free and is pretty short too.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215