Команда создает и управляет Tcl-интерпретаторами.
interp option ?arg arg...?
Эта команда позволяет создавать один или несколько новых Tcl-интерпретаторов, которые сосуществуют в одном приложении с создавшим их интерпретатором. Создавший интерпретатор называется мастер-интерпретатором, а созданные интерпретаторы называются подчиненными (slave) интерпретаторами. Мастер-интерпретатор может создавать произвольное число подчиненных интерпретаторов, а каждый из подчиненных может в свою очередь создавать подчиненные интерпретаторы, для которых он сам является мастер-интерпретатором. В результате в приложении может создаваться иерархия интерпретаторов.
Каждый интерпретатор независим от остальных. Он имеет собственное пространство имен для команд, процедур и глобальных переменных. Мастер-интерпретатор может создавать связи между подчиненными интерпретаторами и собой, используя механизм алиасов. Алиас - это команда в подчиненном интерпретаторе, которая, при ее вызове, вызывает другую команду в мастер-интерпретаторе или в другом подчиненном интерпретаторе. Кроме механизма алиасов, связь между интерпретаторами поддерживается только через переменные окружения. Массив env>обычно является общим для всех интерпретаторов в приложении. Необходимо заметить, что идентификаторы каналов (например, идентификатор, возвращаемый командой open) больше не разделяются между интерпретаторами, как это было в предыдущих версиях Tcl. Чтобы обеспечить совместный доступ к каналам, необходимо использовать явные команды для передачи идентификаторов каналов из интерпретатора в интерпретатор.
Команда interp позволяет также создавать надежные интерпретаторы. Надежный интерпретатор - это интерпретатор с существенно урезанной функциональностью, поэтому он может исполнять ненадежные скрипты без риска нарушить работу вызывающего их приложения. Например, из безопасных интерпретаторов недоступны команды создания каналов и подпроцессов. Более подробно см. Безопасные интерпретаторы. Опасная функциональность не удалена из безопасных интерпретаторов, но скрыта таким образом, что только надежные интерпретаторы могут получить к ней доступ. Более подробно см. Скрытые команды. Механизм алиасов может быть использован для безопасного взаимодействия между подчиненным интерпретатором и его мастер-интерпретатором. Более подробно этот вопрос обсуждается в разделе "Использование алиасов".
Полное имя интерпретатора представляет собой список, содержащий имена его предков в иерархии интерпретаторов и заканчивающийся именем интерпретатора в его непосредственном предке. Имена интерпретаторов в списке - это их относительные имена в их непосредственных мастер-интерпретаторах. Например, если a есть подчиненный интерпретатор текущего интерпретатора и, в свою очередь, имеет подчиненный интерпретатор a1, а тот, в свою очередь, имеет подчиненный интерпретатор a11, то полное имя a11 в a есть список {a1 a11}.
В качестве аргумента описанной ниже команды interp используется полное имя интерпретатора. Интерпретатор, в котором исполняется команда, всегда обозначается как {} (пустая строка). Обратите внимание, что в подчиненном интерпретаторе невозможно сослаться на мастер-интерпретатор кроме как через алиасы. Также нет никакого имени, под которому можно было бы сослаться на мастер-интерпретатор, первым созданный в приложении. Оба ограничения вызваны соображениями безопасности.
Команда interp используется для создания, удаления и выполнения команд в подчиненном интерпретаторе, а также для разделения или передачи каналов между интерпретаторами. Она может иметь одну из перечисленных ниже форм в зависимости от значения аргумента option.
Эта команда создает алиас между двумя подчиненными интерпретаторами (для создания алиаса между подчиненным интерпретатором и мастер-интерпретатором используется команда slave alias). Оба интерпретатора srcPath и targetPath должны быть в иерархии интерпретаторов ниже того интерпретатора, в котором выполняется команда. Аргументы srcPath и srcCmd задают интерпретатор, в котором будет создан алиас и его имя. Аргумент srcPath должен быть Tcl-списком, задающим имя существующего интерпретатора. Например, "a b" определяет интерпретатор b, который является подчиненным интерпретатором интерпретатора a, который в свою очередь является подчиненным интерпретатором текущего интерпретатора. Пустой список соответствует текущему интерпретатору (в котором исполняется команда). Аргумент srcCmd определяет имя новой команды-алиаса, которая будет создана в интерпретаторе srcPath. Аргументы targetPath и targetCmd определяют целевой интерпретатор и команду, а аргументы arg, если они есть, определяют дополнительные аргументы для команды targetCmd, которые будут вставлены перед аргументами, заданным при вызове srcCmd. Команда targetCmd может как существовать, так и не существовать в момент создания алиаса. В последнем случае она не создается командой interp alias.
Алиас позволяет использовать команду targetCmd в интерпретаторе targetPath каждый раз, когда вызывается команда-алиасsrcCmd в интерпретаторе srcPath. Подробнее см. "Использование алиасов".
Создает подчиненный интерпретатор с именем path и новую команду для работы с этим интерпретатором, называемую также подчиненной (slave) командой. Имя подчиненной команды совпадает с последним элементом списка path. Новый подчиненный интерпретатор и подчиненная команда создаются в интерпретаторе, имя которого состоит из всех элементов списка path, кроме последнего. Например, если аргумент path равен a b c, то в результате в интерпретаторе a b будет создан подчиненный интерпретатор c и подчиненная команда c. Синтаксис подчиненной команды описан ниже см. "Команда работы с интерпретатором". Если аргумент path отсутствует, Tcl создает уникальное имя в форме interpx, где x - целое число, и использует его для подчиненного интерпретатора и подчиненной команды. Если в команде указана опция -safe или если мастер-интерпретатор сам является безопасным интерпретатором, новый подчиненный интерпретатор будет безопасным, то есть с ограниченной функциональностью. В противном случае новый интерпретатор будет включать полный набор встроенных Tcl-команд и переменных. Аргумент - используется для того, чтобы обозначить конец опций. Следующий аргумент будет использоваться как имя интерпретатора, даже если он равен -safe.
Команда interp create возвращает имя нового интерпретатора. Имя подчиненного интерпретатора должно быть уникальным среди подчиненных интерпретаторов его мастера. Если у мастер-идентификатора уже существует.
Для каждого подчиненного интерпретатора, созданного с помощью команды interp, в мастер-интерпретаторе создается команда с тем же именем, что и подчиненный интерпретатор. Эта команда предназначена для выполнения различных операций в подчиненном интерпретаторе. В общем случае она имеет следующий вид:
slave command ?arg arg...?
где slave - имя подчиненного интерпретатора, а аргументы command и arg arg... определяют конкретное назначение команды. Ниже перечислены возможные формы команды.
Безопасный интерпретатор - это интерпретатор с ограниченной функциональностью. Поэтому в нем можно без опасений выполнять произвольные скрипты, даже написанные вашим злейшим врагом, не опасаясь нарушить выполнение вашего приложения или испортить содержимое дисков вашего компьютера. Чтобы обеспечить безопасность, из таких интерпретаторов удалены определенные команды и переменные. Например, команда создания файлов на диске и команда запуска подпроцессов. Тем не менее, в безопасном интерпретаторе можно обеспечить ограниченный доступ к подобным командам с помощью механизма алиасов. В результате при выполнении потенциально опасных команд будут вызываться специально написанные процедуры в мастер-интерпретаторе, которые могут тщательно проверять заданные аргументы и позволять использовать только ограниченный набор средств. Например, создание файлов может быть разрешено только в ограниченном наборе подкаталогов, а запуск подпроцессов разрешен только для ограниченного (и фиксированного) набора хорошо проверенных программ.
Чтобы создаваемый интерпретатор был безопасным, необходимо при его создании указать опцию -safe. Кроме того, любой интерпретатор, созданный из безопасного интерпретатора, также будет безопасным.
Безопасный интерпретатор создается со следующим набором команд:
Следующие команды в безопасном интерпретаторе скрыты:
cd | exec | exit | fconfigure |
file | glob | load | open |
pwd | socket | source |
Эти команды могут быть созданы заново как Tcl-процедуры или алиасы или разрешены к использованию с помощью команды interp expose.
Сверх того, в безопасных интерпретаторах отсутствует массив env, содержащий обычно переменные окружения. Это связано с тем, что в переменных окружения может храниться конфиденциальная информация.
Расширения, загружаемые в безопасный интерпретатор, также обладают ограниченной функциональностью. Более подробно эти вопросы обсуждаются в пп. SafeTcl и 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. Безопасный интерпретатор не может изменить набор скрытых команд в себе или своих потомках.
В настоящее время имена скрытых команд не могут содержать имени пространства имен. Поэтому, прежде чем скрыть команду, ее надо перевести в глобальное пространство имен. Команды, которые необходимо скрыть, должны находиться в глобальном пространстве имен. Это позволяет избежать ошибочного скрытия одноименной команды из другого пространства имен.