0

I want to construct a complicate variable, let's see :

set entry_arg [lindex $argv 1]
set command_to_launch {extrernal_command_tool -option "set var $entry_arg" -other_option}
exec $command_to_lauch

The command is launched, no problem ...

but, the problem is that the tool get $entry_arg and crash ... This is due to the " " that don't allow tcl to interpret de variable

set command_to_launch {extrernal_command_tool -option "set var [lindex $argv 1]"  -other_option}

Have the same problem !

How can I solve it ?

heyhey
  • 191
  • 2
  • 12

2 Answers2

6

You should construct the contents of command_to_launch with the list command.

set command_to_launch [list \
    extrernal_command_tool -option "set var [lindex $argv 1]" -other_option]

You would the run this with either one of these:

exec {*}$command_to_launch           ; # For 8.5 or 8.6
eval exec $command_to_launch         ; # For 8.4 or before

Pick the right one for which version of the language you're using, of course.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • The other alternative is to construct a Bourne shell script (using that language's syntactic features) and then to execute it with `exec /bin/sh -c $theScriptFile`; that's sometimes the best option due to user expectations. – Donal Fellows Jan 31 '13 at 14:00
  • Ok it is better, but in my -other_option I have some [ ] ! so the eval make an error for this now ! – heyhey Jan 31 '13 at 15:10
  • your method also turn the " " into { } and make the external tool crash ! – heyhey Jan 31 '13 at 15:18
  • @heyhey Your cluelessness is quite deep, I see. The words of the list become independent arguments to the subprocess (with appropriate quoting on Windows, or direct separation on Unix) so any brackets or braces are the ones in your data. Your complaint indicates that whatever is going on is _not what you're telling us_ is going on; at that point, I at least really don't care to try to fix it any more. – Donal Fellows Jan 31 '13 at 15:55
  • Sorry about that i was very unclear in my question. my other option was an other variable, so I was not taking care about that.I tried to simplify the problem. I assume that the ! at the end of my remarks was not very clever. Thanks for your help. – heyhey Feb 01 '13 at 07:51
  • 1
    @heyhey, be sure to read [this chapter of The Book](http://beedub.com/book/3rd/Eval.pdf) to get understanding of why you should use `list` to construct scripts for `eval`. – kostix Feb 02 '13 at 14:02
1

The problem isn't "", it's {}. Try:

set entry_arg [lindex $argv 0]
set command_to_launch "extrernal_command_tool -option $entry_arg -other_option"
set output [eval exec $command_to_lauch]

You need to learn about interpolation, quoting and braces, like this: Understanding the usage of braces

(Also, I suspect you want to use [lindex $argv 0] -- TCL uses the variable argv0 as the program name, and the arguments start at index 0, unlike C and other languages.)

Edit: You might actually mean this, if you really want a quoted argument like "set var xxx":

    set command_to_launch "extrernal_command_tool -option \"set var $entry_arg\" -other_option"
Community
  • 1
  • 1
mr.spuratic
  • 9,767
  • 3
  • 34
  • 24
  • This method is not the most robust TCL, it's cheating a little because it only works when `command_to_launch` is a simple string. In the general case (and especially when using `eval` for other purposes) using a `list` as shown in the other answer is the correct and robust approach. That method makes sure everything is parsed correctly, though you have understand how it interacts with quotes and `$`/`[`/`#`. @kostix's link below is good reading too. – mr.spuratic Mar 04 '13 at 21:13