How to add a variable amount of arguments to exec

2019-02-21 21:14发布

问题:

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?

回答1:

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



回答2:

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.