2015-02-12 2 views
1

Я немного смущен exec и eval в Tcl. В следующем примере:tcl: eval и exec confusing point

set cmd "mkdir new_folder"; 
exec $cmd 

не работает с сообщением об ошибке: couldn't execute "mkdir new_folder" no such file or directory. и eval работает

set cmd "mkdir new_folder"; 
eval exec $cmd 

Я также попробовал этот путь:

set cmd_1 "mkdir"; 
set cmd_2 "new_folder" 
exec $cmd_1 $cmd_2 

Он также работает Что ж. так в чем причина?

+3

Хорошо, я знаю, что знаю причину. Первая программа не удалась, поскольку она рассматривает 'mkdir new_folder' как программу для вызова, поскольку она помещается внутри одной строки; и вторая программа работает, поскольку 'eval' concat следующую часть в список команд; и третий работает, так как я передаю две разделенные строки в 'exec'. –

+1

Если вы просто создаете каталоги, проверьте 'файл mkdir' ... –

ответ

4

Где вы действительно должны следить, когда один из ваших параметров содержит пробелы. В этом случае, eval не будет знать, что делать:

% set cmd "mkdir 'dir with spaces'" 
mkdir 'dir with spaces' 
% eval exec $cmd 
% exec ls -l 
total 20 
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 'dir 
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 spaces' 
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 with 

То, что вы действительно хотите сделать, это использовать список. Тогда Tcl точно понимает, что отдельные элементы

% set cmd [list mkdir "dir with spaces"] 
mkdir {dir with spaces} 
% exec {*}$cmd 
% exec ls -l 
total 24 
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 'dir 
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:53 dir with spaces 
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 spaces' 
drwxr-xr-x 2 glennj glennj 4096 Feb 12 07:51 with 
2

Как уже видно из вашего собственного комментария, проблема связана с интерпретацией параметров. Если вы все еще хотите иметь команду в строке sinlge, вы можете использовать оператор расширения {*}.

set cdm "mkdir new_folder" 
exec {*}$cmd ;# Tcl 8.5 or higher 
eval exec $cmd ;# alternative solution 

Это относится не только к команде exec. Общее правило: если команда принимает несколько параметров и говорит, что они сохраняются в переменной params, когда вы вызываете команду, параметры должны быть расширены: cmd {*}$params. Таким образом, эти следующие сценарии equivlent

cmd par1 par2 

и

set params "para1 par2" 
cmd {*}$params 
+0

О, спасибо. {*} также работает для меня. Это альтернативный метод, спасибо. –

1

Я вижу этот пост стар, я просто положил мой ответ, как мой друг спросил об этом. Итак, создавая изображение, вы просто выполняете команду в оболочке bash и хотите создать каталог.В этом случае вы должны запускать:

  • mkdir new_folder

Но теперь визуализации, что произойдет, если вы запустите ту же команду следующим образом:

  • "mkdir new_folder"

Конечно если будет выдано сообщение об ошибке:

Баш: MkDir new_folder: команда не найдена

Теперь то же самое с командой TCL ехес, когда вы передаете все как один аргумент для EXEC он идет так же, как на баш:

  • Exec "MkDir new_filder" # фактически выполнить:
  • "MkDir new_folder" # в Баш и Hense выдаст ошибку

Теперь почему помогает eval? просто потому, что он удаляет области после оценки в TCL, и вы фактически выполняете: exec mkdir new_folder

Надеюсь, это поможет!

Смежные вопросы