1

I'm working on a file explorer inTCL/Tk and I want to add a little thing to execute commands with the current selection (using %l %f) %l executing with the full list and %f executing the commmand with each file. my only problem is that if I type a command like "gedit" for eg it works but as soon as I type a command with argument it doesn't work ... I've been looking everywhere and I don't get it... If someone could help me... btw getl var Name is a function that returns me a FileName in full path (/home/...) and if I return the string that is supposed to be executed and put it in a terminal it works...

Here is the code:

proc tl_exec {liste command } {
#lorsqu'il faut effectué la commande avec la liste en param
if { [string first "%l" $command] > 0} {
  foreach v $liste {
     lappend args [getl $v Name]
  } 
    set com [string map [list "%l" [join $args " "] ] $command ]
  puts $com
    set val [exec [split $com " "] ]
} elseif { [string first "%f" $command] > 0} {
#lorsqu'il faut effectué la commande pour chaque fichier        
  foreach v $liste {
            set com [string map list ["%f" [getl $v "Name"] ] $command ]
            lappend val [ exec [split $com " "] ]
    }
} else {
#lorsqu'on a pas de fichiers 
    set val [exec $command]
}
}

Thanks a lot

2
  • Ho yes btw the error that is return for anything is "couldn't execute no such file or directory..." I guess it's something to do with the absens of magic quotes and the fact the it considers everything as a single command... Commented May 10, 2011 at 17:53
  • Well lets say I'm stupid and can't open my eyes :) Just found out : I've got to use eval exec to have the thing... Sorry for the auto answer question... BTW found a useful link "common mistakes in TCL/TK" :phaseit.net/claird/comp.lang.tcl/fmm.html Commented May 10, 2011 at 18:01

1 Answer 1

5

Your code has more than a single problem, it will probably break with special chars or spaces in filenames too, as you do not quoting at all.

But you are right about exec considering everything as a single command.

set val [exec [split $com " "] ]

does not do what you expect, split returns a list, but does not automagically turn that list into extra args for exec.

If you use Tcl 8.5 you can try:

set val [exec {*}[split $com " "] ]

which turns the list into single arguments to pass to exec.

But the code you use is brittle in general, as you do not handle any exit codes or programs writing to stderr, so a more elaborate solution would be needed to be robust.

Have a look at http://wiki.tcl.tk/1039 especially the discussions on the bottom of the page.

Sign up to request clarification or add additional context in comments.

4 Comments

well yes but I was testing at first... thanks for the help I have an old version of Tcl which doesn't have {*} how can I replace it?
You can use set val [eval exec [split $com " "] ]. That has quite a few security issues though.
That'll have the same security issues as the version with {*}, as split is guaranteed to produce a proper list.
I was wrong, about extra security issues, as Donal pointed out. If you didn't use the split construction like you did, but had passed in the string directly, it would have had extra security issues due to evaling the string. But as split produces a proper list, the eval is safe from code injection or other nastyness.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.