Команда создает и управляет Tcl-интерпретаторами.СИНТАКСИС
interp option?arg arg...?ОПИСАНИЕ
Эта команда позволяет создавать один или несколько новых Tcl-интерпретаторов, которые сосуществуют в одном приложении с создавшим их интерпретатором. Создавший интерпретатор называется мастер-интерпретатором, а созданные интерпретаторы называются подчиненными (slave) интерпретаторами. Мастер-интерпретатор может создавать произвольное число подчиненных интерпретаторов, а каждый из подчиненных может в свою очередь создавать подчиненные интерпретаторы, для которых он сам является мастер-интерпретатором. В результате в приложении может создаваться иерархия интерпретаторов.
Каждый интерпретатор независим от остальных. Он имеет собственное пространство имен для команд, процедур и глобальных переменных. Мастер-интерпретатор может создавать связи между подчиненными интерпретаторами и собой, используя механизм алиасов. Алиас — это команда в подчиненном интерпретаторе, которая, при ее вызове, вызывает другую команду в мастер-интерпретаторе или в другом подчиненном интерпретаторе. Кроме механизма алиасов, связь между интерпретаторами поддерживается только через переменные окружения. Массив envобычно является общим для всех интерпретаторов в приложении. Необходимо заметить, что идентификаторы каналов (например, идентификатор, возвращаемый командой open) больше не разделяются между интерпретаторами, как это было в предыдущих версиях Tcl. Чтобы обеспечить совместный доступ к каналам, необходимо использовать явные команды для передачи идентификаторов каналов из интерпретатора в интерпретатор.
Команда interp позволяет также создавать надежные интерпретаторы. Надежный интерпретатор — это интерпретатор с существенно урезанной функциональностью, поэтому он может исполнять ненадежные скрипты без риска нарушить работу вызывающего их приложения. Например, из безопасных интерпретаторов недоступны команды создания каналов и подпроцессов. Более подробно см. “Безопасные интерпретаторы”. Опасная функциональность не удалена из безопасных интерпретаторов, но скрыта таким образом, что только надежные интерпретаторы могут получить к ней доступ. Более подробно см. “Скрытые команды”. Механизм алиасов может быть использован для безопасного взаимодействия между подчиненным интерпретатором и его мастер-интерпретатором. Более подробно этот вопрос обсуждается в разделе " Использование алиасов".
Полное имя интерпретатора представляет собой список, содержащий имена его предков в иерархии интерпретаторов и заканчивающийся именем интерпретатора в его непосредственном предке. Имена интерпретаторов в списке — это их относительные имена в их непосредственных мастер-интерпретаторах. Например, если a есть подчиненный интерпретатор текущего интерпретатора и, в свою очередь, имеет подчиненный интерпретатор a1, а тот, в свою очередь, имеет подчиненный интерпретатор a11, то полное имя a11 в a есть список {a1 a11}.
В качестве аргумента описанной ниже команды interp используется полное имя интерпретатора. Интерпретатор, в котором исполняется команда, всегда обозначается как {} (пустая строка). Обратите внимание, что в подчиненном интерпретаторе невозможно сослаться на мастер-интерпретатор кроме как через алиасы. Также нет никакого имени, под которому можно было бы сослаться на мастер-интерпретатор, первым созданный в приложении. Оба ограничения вызваны соображениями безопасности.КОМАНДА INTERP
Команда interp используется для создания, удаления и выполнения команд в подчиненном интерпретаторе, а также для разделения или передачи каналов между интерпретаторами. Она может иметь одну из перечисленных ниже форм в зависимости от значения аргумента option.
interp alias srcPath srcCmd
Эта команда создает алиас между двумя подчиненными интерпретаторами (для создания алиаса между подчиненным интерпретатором и мастер-интерпретатором используется команда slave alias). Оба интерпретатора srcPath и targetPath должны быть в иерархии интерпретаторов ниже того интерпретатора, в котором выполняется команда. Аргументы srcPath и srcCmd задают интерпретатор, в котором будет создан алиас и его имя. Аргумент srcPath должен быть Tcl-списком, задающим имя существующего интерпретатора. Например, “a b'' определяет интерпретатор b, который является подчиненным интерпретатором интерпретатора a, который в свою очередь является подчиненным интерпретатором текущего интерпретатора. Пустой список соответствует текущему интерпретатору (в котором исполняется команда). Аргумент srcCmd определяет имя новой команды-алиаса, которая будет создана в интерпретаторе srcPath. Аргументы targetPath и targetCmd определяют целевой интерпретатор и команду, а аргументы arg, если они есть, определяют дополнительные аргументы для команды targetCmd, которые будут вставлены перед аргументами, заданным при вызове srcCmd. Команда targetCmd может как существовать, так и не существовать в момент создания алиаса. В последнем случае она не создается командой interp alias.
Команда interp create возвращает
имя нового интерпретатора. Имя подчиненного интерпретатора должно быть
уникальным среди подчиненных интерпретаторов его мастера. Если у мастер-идентификатора
уже существу
Для каждого подчиненного интерпретатора, созданного с помощью команды interp, в мастер-интерпретаторе создается команда с тем же именем, что и подчиненный интерпретатор. Эта команда предназначена для выполнения различных операций в подчиненном интерпретаторе. В общем случае она имеет следующий вид:
slave command?arg arg...?БЕЗОПАСНЫЕ ИНТЕРПРЕТАТОРЫгде slave — имя подчиненного интерпретатора, а аргументы command и arg arg... определяют конкретное назначение команды. Ниже перечислены возможные формы команды.
slave aliases
slave alias srcCmd Возвращает список всех алиасов в подчиненном интерпретаторе slave. Возвращаемые имена — это имена, использовавшиеся при создании соответствующих алиасов. Они могут не совпадать с текущими именами команд, если те были переименованы. slave alias srcCmd {} Возвращает список, состоящий из имени реальной команды и ее аргументов, ассоциированных с алиасом srcCmd. Возвращаются те же значения, что и в команде создания алиаса. Если созданный алиас был переименован, то в команде надо указывать имя srcCmd, которое использовалось при создании алиаса. slave alias srcCmd targetCmd?arg..? Удаляет алиас srcCmd в подчиненном интерпретаторе. Аргумент srcCmd указывает имя алиаса в момент создания. Если после этого он был переименован, удалится переименованная команда. slave eval arg?arg..? Эта команда создает команду — алиас в подчиненном интерпретаторе. Каждый раз, когда в подчиненном интерпретаторе будет вызываться команда srcCmd, реально выполняться будет команда targetCmd в мастер-интерпретаторе. Аргументы arg, если они есть, определяют дополнительные аргументы для команды targetCmd, которые будут вставлены перед аргументами, заданными при вызове srcCmd. Подробнее см. “Использование алиасов”. slave expose hiddenName?exposedCmdName? Эта команда объединяет все свои аргументы так же, как команда concat, и выполняет сформированный таким образом скрипт в подчиненном интерпретаторе. Результат выполнения (включая информацию об ошибках в переменных errorInfoи errorCode, если произошла ошибка) возвращается в вызывающий интерпретатор. slave hide exposedCmdName?hiddenCmdName? Разрешает использование в подчиненном интерпретаторе скрытой команды hiddenName под новым именем exposedCmdName (в настоящее время поддерживаются только имена в глобальном пространстве имен, не содержащие “::”). Если обычная (не скрытая) команда exposedCmdName уже существует, генерируется сообщение об ошибке. Скрытые команды обсуждаются ниже (см. ”Скрытые команды ”). slave hidden Запрещает использование в подчиненном интерпретаторе обычной команды exposedCmdName и переименовывает ее в скрытую команду hiddenCmdName (или в скрытую команду под старым именем, если новое не было задано). Если скрытая команда с заданным именем уже существует, команда возвращает ошибку. В настоящее время exposedCmdName и hiddenCmdName не могут содержать “::”. Команды, которые должны быть скрыты с помощью interp hide, ищутся только в глобальном пространстве имен, даже если текущее пространство имен не глобальное. Скрытые команды обсуждаются ниже (см. ”Скрытые команды ”). slave i nvokehidden?-global hiddenName?arg..? Возвращает список скрытых команд в подчиненном интерпретаторе. slave issafe Вызывает в подчиненном интерпретаторе скрытую команду hiddenCmdName с перечисленными аргументами. Никаких подстановок или вычислений в аргументах не производится. Если указана опция -global, скрытая команда выполняется на глобальном уровне в подчиненном интерпретаторе. В противном случае она выполняется в текущем контексте и может использовать значения локальных переменных и переменных из вышестоящих стеков. Скрытые команды обсуждаются подробно в соответствующем разделе ниже. slave marktrusted Возвращает ‘1’, если подчиненный интерпретатор безопасный, и ‘0’ в противном случае. Отмечает подчиненный интерпретатор как надежный. Не раскрывает скрытые команды. Команда может выполняться только из надежного интерпретатора. Если подчиненный интерпретатор уже надежный, команда не оказывает никакого воздействия.
Безопасный интерпретатор — это интерпретатор с ограниченной функциональностью. Поэтому в нем можно без опасений выполнять произвольные скрипты, даже написанные вашим злейшим врагом, не опасаясь нарушить выполнение вашего приложения или испортить содержимое дисков вашего компьютера. Чтобы обеспечить безопасность, из таких интерпретаторов удалены определенные команды и переменные. Например, команда создания файлов на диске и команда запуска подпроцессов. Тем не менее, в безопасном интерпретаторе можно обеспечить ограниченный доступ к подобным командам с помощью механизма алиасов. В результате при выполнении потенциально опасных команд будут вызываться специально написанные процедуры в мастер-интерпретаторе, которые могут тщательно проверять заданные аргументы и позволять использовать только ограниченный набор средств. Например, создание файлов может быть разрешено только в ограниченном наборе подкаталогов, а запуск подпроцессов разрешен только для ограниченного (и фиксированного) набора хорошо проверенных программ.
Чтобы создаваемый интерпретатор был безопасным, необходимо при его создании указать опцию -safe. Кроме того, любой интерпретатор, созданный из безопасного интерпретатора, также будет безопасным.
Безопасный интерпретатор создается со следующим набором команд:
Следующие команды в безопасном интерпретаторе скрыты:
ИСПОЛЬЗОВАНИЕ АЛИАСОВ
cd exec exit fconfigure file glob load open pwd socket source
Эти команды могут быть созданы заново как Tcl-процедуры или алиасы или разрешены к использованию с помощью команды interp expose.
Сверх того, в безопасных интерпретаторах отсутствует массив env, содержащий обычно переменные окружения. Это связано с тем, что в переменных окружения может храниться конфиденциальная информация.
Расширения, загружаемые в безопасный интерпретатор, также обладают ограниченной функциональностью. Более подробно эти вопросы обсуждаются в пп. Safe-Tcl и load .
Механизм алиасов весьма тщательно спроектирован таким образом, чтобы он позволял без опасений выполнять ненадежные скрипты в безопасных подчиненных интерпретаторах, используя для алиасов проверенные команды в мастер-интерпретаторах. Для обеспечения безопасности принципиально важно, чтобы информация из подчиненного интерпретатора никогда не обрабатывалась (то есть скрипты не исполнялись, и в них не производились подстановки) в мастер-интерпретаторе. В противном случае всегда будет оставаться возможность написать такой скрипт для подчиненного интерпретатора, который выполнил бы произвольные действия в мастер-интерпретаторе и мог бы нарушить его безопасность.СКРЫТЫЕ КОМАНДЫКогда в подчиненном интерпретаторе вызывается команда-алиас, необходимые Tcl-подстановки в аргументах выполняются там же, как для обычной Tcl-команды. После этого аргументы объединяются с целевой командой и ее аргументами, определенными при создании алиаса. Так, если команда вызова алиаса имела вид ``srcCmd arg1 arg2... argN'', то сформируется команда `targetCmd arg arg... arg arg1 arg2... argN'', где arg arg... arg – аргументы, указанные при создании алиаса. После этого сформированная команда выполняется в целевом интерпретаторе (со сформированным набором аргументов). Если в целевом интерпретаторе нет команды targetCmd, будет сгенерирована ошибка. Перед выполнением команды в целевом интерпретаторе больше никаких подстановок в аргументах произведено не будет. Команда будет вызвана напрямую, а не через обычный механизм выполнения. Таким образом, подстановки в каждом слове команды оказываются выполненными ровно один раз: в targetCmd и arg... arg – при выполнении команды, с помощью которой был создан алиас, а в arg1 — argN — при анализе команды алиаса в соответствующем интерпретаторе.
При написании процедуры targetCmd, которую предполагается использовать для алиаса в безопасном интерпретаторе, нужно придерживаться следующего правила. Недопустимо, чтобы в значениях ее аргументов в теле процедуры производились подстановки, либо чтобы аргументы были скриптами, исполняемыми в теле процедуры. Нарушение этого правила дает возможность подчиненному интерпретатору выполнить произвольный код в мастер-интерпретаторе и нарушить, таким образом, безопасность системы.
Безопасные интерпретаторы существенно ограничивают функциональные возможности выполняемых в них Tcl-скриптов. С одной стороны, это позволяет избежать нежелательных последствий при их исполнении, но, с другой стороны, рано или поздно возникает насущная необходимость выполнить потенциально опасную команду в безопасном интерпретаторе. Например, прочитать дополнительный скрипт с помощью команды source. Или выполнить в Tk-приложении некоторые команды управления окнами.Команда interp обеспечивает решение этой проблемы с помощью механизма скрытых команд. Потенциально опасные команды не удаляются из безопасного интерпретатора, а становятся скрытыми. При этом их невозможно выполнить из скрипта, выполняемого “внутри” интерпретатора. Но их можно выполнить “извне” из любого надежного предка интерпретатора с помощью команды interp invoke. Скрытые и обычные (не скрытые) команды размещаются в различных пространствах имен. Это позволяет иметь в одном интерпретаторе скрытую и обычную команды с одним и тем же именем.
Скрытые команды могут использоваться в теле процедуры, использованной при определении алиаса. Например, в подчиненном интерпретаторе можно создать алиас source. Вызываемая при этом процедура в мастер-интерпретаторе проверяет допустимость запрошенной операции (например, что запрошенный файл находится в соответствующем каталоге, к которому разрешен доступ из подчиненного интерпретатора) и вызывает в подчиненном интерпретаторе скрытую команду source. Обратите внимание, что в этом случае в подчиненном интерпретаторе существует две команды source: скрытая и алиас.
Из мастер-интерпретатора возможен вызов скрытых команд подчиненного интерпретатора через механизм алиасов. Поэтому в теле процедур, предназначенных для создания алиаса, необходимо избегать подстановок и команд исполнения для аргументов. См. “ Использование алиасов” .
Безопасные интерпретаторы не могут “изнутри” вызвать скрытую команду в себе или своих потомках.
Множество скрытых команд может быть изменено из надежного интерпретатора с помощью команд interp expose и interp hide. Безопасный интерпретатор не может изменить набор скрытых команд в себе или своих потомках.
В настоящее время имена скрытых команд не могут содержать имени пространства имен. Поэтому, прежде чем скрыть команду, ее надо перевести в глобальное пространство имен. Команды, которые необходимо скрыть, должны находиться в глобальном пространстве имен. Это позволяет избежать ошибочного скрытия одноименной команды из другого пространства имен.