tcl exec с файлом в параметре не работает

#file #arguments #exec #tcl

#файл #аргументы #exec #tcl

Вопрос:

Я работаю над проводником файлов inTCL / Tk и хочу добавить небольшую деталь для выполнения команд с текущим выбором (используя %l %f). %l выполняется с полным списком, а %f выполняет команду commmand с каждым файлом. моя единственная проблема в том, что если я ввожу команду типа «gedit», например, это работает, но как только я ввожу команду с аргументом, она не работает… Я искал везде, и я этого не понимаю… Если бы кто-нибудь мог мне помочь … кстати, getl var Name — это функция, которая возвращает мне имя файла с полным путем (/home / …), и если я возвращаю строку, которая должна быть выполнена, и помещаю ее в терминал, она работает…

Вот код:

 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]
}
}
  

Большое спасибо

Комментарии:

1. Ho да, кстати, ошибка, которая возвращается для чего угодно, — «не удалось выполнить такой файл или каталог …» Я предполагаю, что это как-то связано с отсутствием магических кавычек и тем фактом, что он рассматривает все как единую команду…

2. Ну, допустим, я глуп и не могу открыть глаза 🙂 Только что выяснил: я должен использовать eval exec, чтобы иметь эту вещь… Извините за вопрос с автоматическим ответом… Кстати, нашел полезную ссылку «распространенные ошибки в TCL / TK»: phaseit.net/claird/comp.lang.tcl/fmm.html

Ответ №1:

В вашем коде больше одной проблемы, вероятно, он также будет прерываться из-за специальных символов или пробелов в именах файлов, поскольку вы вообще не используете кавычки.

Но вы правы в том, что exec рассматривает все как единую команду.

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

делает не то, что вы ожидаете, split возвращает список, но автоматически не превращает этот список в дополнительные аргументы для exec.

Если вы используете Tcl 8.5, вы можете попробовать:

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

который превращает список в отдельные аргументы для передачи в exec.

Но используемый вами код в целом хрупкий, поскольку вы не обрабатываете никаких кодов выхода или программ, записываемых в stderr, поэтому для обеспечения надежности потребуется более сложное решение.

Взгляните на http://wiki.tcl.tk/1039 особенно обсуждения внизу страницы.

Комментарии:

1. ну да, но сначала я тестировал … спасибо за помощь, у меня старая версия Tcl, в которой нет {*} как я могу ее заменить?

2. Вы можете использовать set val [eval exec [split $ com » «] ] . Однако у этого есть немало проблем с безопасностью.

3. Это будет иметь те же проблемы с безопасностью, что и версия с {*} , поскольку split гарантируется создание правильного списка.

4. Я был неправ насчет дополнительных проблем безопасности, как указал Донал. Если бы вы не использовали разделенную конструкцию, как вы это делали, а передали строку напрямую, у нее были бы дополнительные проблемы с безопасностью из-за вычисления строки. Но поскольку split создает правильный список, оценка защищена от внедрения кода или других неприятностей.