projman/hlp/ru/tcl/interp.html
2018-02-05 17:23:37 +03:00

744 lines
51 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>
<html>
<head>
<title>interp</title>
</head>
<body>
<h1>interp</h1>
<p> Команда создает и управляет Tcl-интерпретаторами. </p>
<h2>СИНТАКСИС</h2>
<pre>
<strong>interp</strong> <em>option</em> ?<em>arg</em> <em>arg</em>...?
</pre>
<h2>ОПИСАНИЕ</h2>
<p>Эта команда позволяет создавать один или несколько новых
Tcl-интерпретаторов, которые сосуществуют в одном приложении с
создавшим их интерпретатором. Создавший интерпретатор называется
мастер-интерпретатором, а созданные интерпретаторы называются
подчиненными (<em>slave</em>) интерпретаторами.
Мастер-интерпретатор может создавать произвольное число
подчиненных интерпретаторов, а каждый из подчиненных может в
свою очередь создавать подчиненные интерпретаторы, для которых
он сам является мастер-интерпретатором. В результате в
приложении может создаваться иерархия интерпретаторов.
</p>
<p>Каждый интерпретатор независим от остальных. Он имеет
собственное пространство имен для команд, процедур и глобальных
переменных. Мастер-интерпретатор может создавать связи между
подчиненными интерпретаторами и собой, используя механизм
алиасов. Алиас - это команда в подчиненном интерпретаторе,
которая, при ее вызове, вызывает другую команду в
мастер-интерпретаторе или в другом подчиненном
интерпретаторе. Кроме механизма алиасов, связь между
интерпретаторами поддерживается только через переменные
окружения. Массив <a
href=tclvars.html#env><strong>env</strong></a>>обычно является общим для
всех интерпретаторов в приложении. Необходимо заметить, что
идентификаторы каналов (например, идентификатор, возвращаемый
командой <a href= open.html><strong>open</strong></a>) больше не
разделяются между интерпретаторами, как это было в предыдущих
версиях Tcl. Чтобы обеспечить совместный доступ к каналам,
необходимо использовать явные команды для передачи
идентификаторов каналов из интерпретатора в интерпретатор.
</p>
<p>Команда <strong>interp</strong> позволяет также создавать надежные
интерпретаторы. Надежный интерпретатор - это интерпретатор с
существенно урезанной функциональностью, поэтому он может
исполнять ненадежные скрипты без риска нарушить работу
вызывающего их приложения. Например, из безопасных
интерпретаторов недоступны команды создания каналов и
подпроцессов. Более подробно см. <a href=
#БЕЗОПАСНЫЕ>Безопасные интерпретаторы</a>. Опасная
функциональность не удалена из безопасных интерпретаторов, но
скрыта таким образом, что только надежные интерпретаторы могут
получить к ней доступ. Более подробно см. <a href=
#СКРЫТЫЕ КОМАНДЫ>Скрытые команды</a>. Механизм
алиасов может быть использован для безопасного взаимодействия
между подчиненным интерпретатором и его
мастер-интерпретатором. Более подробно этот вопрос обсуждается в
разделе &quot;<a
href=#ИСПОЛЬЗОВАНИЕ АЛИАСОВ>Использование алиасов</a>&quot;.
</p>
<p>Полное имя интерпретатора представляет собой список, содержащий
имена его предков в иерархии интерпретаторов и заканчивающийся
именем интерпретатора в его непосредственном предке. Имена
интерпретаторов в списке - это их относительные имена в их
непосредственных мастер-интерпретаторах. Например, если <strong>a</strong>
есть подчиненный интерпретатор текущего интерпретатора и, в свою
очередь, имеет подчиненный интерпретатор <strong>a1</strong>, а тот, в
свою очередь, имеет подчиненный интерпретатор <strong>a11</strong>, то
полное имя <strong>a11</strong> в <strong>a</strong> есть список <strong>{a1 a11}</strong>.
</p>
<p>В качестве аргумента описанной ниже команды <strong>interp</strong>
используется полное имя интерпретатора. Интерпретатор, в котором
исполняется команда, всегда обозначается как <strong>{}</strong> (пустая
строка). Обратите внимание, что в подчиненном интерпретаторе
невозможно сослаться на мастер-интерпретатор кроме как через
алиасы. Также нет никакого имени, под которому можно было бы
сослаться на мастер-интерпретатор, первым созданный в
приложении. Оба ограничения вызваны соображениями безопасности.
</p>
<h2>КОМАНДА INTERP</h2>
<p> Команда <strong>interp</strong> используется для создания, удаления и
выполнения команд в подчиненном интерпретаторе, а также для
разделения или передачи каналов между интерпретаторами. Она
может иметь одну из перечисленных ниже форм в зависимости от
значения аргумента <em>option</em>.
</p>
<dl>
<dt> <a name=alias></a><strong>interp</strong> <strong>alias</strong>
<em>srcPath</em> <em>srcCmd</em></dt>
<dd>Возвращает список, состоящий из исходной команды и
аргументов, связанных с алиасом <em>srcCmd</em> в интерпретаторе
<em>srcPath</em> (возвращаются значения, использовавшиеся при
создании алиаса, так как имя команды могло быть изменено с
помощью команды <a href= rename.html><strong>rename</strong></a>).
</dd>
<dt><strong>interp</strong> <strong>alias</strong> <em>srcPath</em> <em>srcCmd</em>
<em>{}</em></dt>
<dd>Удаляет алиас <em>srcCmd</em> в подчиненном интерпретаторе
<em>srcPath</em>. Имя <em>srcCmd</em> - это имя, под которым алиас
был создан. Если созданная команда была переименована, то
будет удалена переименованная команда.
</dd>
<dt><strong>interp</strong> <strong>alias</strong> <em>srcPath</em> <em>srcCmd</em>
<em>targetPath</em> <em>targetCmd</em> ?<em>arg</em> <em>arg</em>...?</dt>
<dd><p>Эта команда создает алиас между двумя подчиненными
интерпретаторами (для создания алиаса между подчиненным
интерпретатором и мастер-интерпретатором используется
команда <strong>slave alias</strong>). Оба интерпретатора <em>
srcPath</em> и <em>targetPath</em> должны быть в иерархии
интерпретаторов ниже того интерпретатора, в котором
выполняется команда. Аргументы s<em>rcPath</em> и <em>
srcCmd</em> задают интерпретатор, в котором будет создан
алиас и его имя. Аргумент s<em>rcPath</em> должен быть
Tcl-списком, задающим имя существующего интерпретатора.
Например, &quot;<strong>a b</strong>&quot; определяет интерпретатор
<strong>b</strong>, который является подчиненным интерпретатором
интерпретатора <strong>a</strong>, который в свою очередь является
подчиненным интерпретатором текущего интерпретатора. Пустой
список соответствует текущему интерпретатору (в котором
исполняется команда). Аргумент <em>srcCmd</em> определяет имя
новой команды-алиаса, которая будет создана в интерпретаторе
s<em>rcPath</em>. Аргументы <em>targetPath</em> и
<em>targetCmd</em> определяют целевой интерпретатор и команду,
а аргументы <em>arg</em>, если они есть, определяют
дополнительные аргументы для команды <em>targetCmd</em>,
которые будут вставлены перед аргументами, заданным при
вызове srcCmd. Команда <em>targetCmd</em> может как
существовать, так и не существовать в момент создания
алиаса. В последнем случае она не создается командой
<strong>interp alias.</strong></p>
<p> Алиас позволяет использовать команду <em>targetCmd</em> в
интерпретаторе <em>targetPath</em> каждый раз, когда
вызывается команда-алиас<em>srcCmd</em> в интерпретаторе <em>
srcPath</em>. Подробнее см. &quot;Использование алиасов&quot;.
</p>
</dd>
<dt><strong>interp</strong> <strong>aliases</strong> ?<em>path</em>?</dt>
<dd> Эта команда возвращает список имен всех команд-алиасов,
определенных в интерпретаторе <em>path</em>.
</dd>
<dt><strong>interp</strong> <strong>create</strong> ?<em>-safe</em>? ?<em>--</em>?
?<em>path</em>?</dt>
<dd><p>Создает подчиненный интерпретатор с именем <em>path</em> и
новую команду для работы с этим интерпретатором, называемую
также подчиненной (slave) командой. Имя подчиненной команды
совпадает с последним элементом списка <em>path</em>. Новый
подчиненный интерпретатор и подчиненная команда создаются в
интерпретаторе, имя которого состоит из всех элементов
списка <em>path</em>, кроме последнего. Например, если
аргумент <em>path</em> равен <strong>a b c</strong>, то в результате в
интерпретаторе <strong>a b</strong> будет создан подчиненный
интерпретатор <strong>c</strong> и подчиненная команда <strong>c</strong>.
Синтаксис подчиненной команды описан ниже см. &quot;Команда
работы с интерпретатором&quot;. Если аргумент <em>path</em>
отсутствует, Tcl создает уникальное имя в форме <strong>
interp</strong>x, где <em>x</em> - целое число, и использует его
для подчиненного интерпретатора и подчиненной команды. Если
в команде указана опция <strong>-safe</strong> или если
мастер-интерпретатор сам является безопасным
интерпретатором, новый подчиненный интерпретатор будет
безопасным, то есть с ограниченной функциональностью. В
противном случае новый интерпретатор будет включать полный
набор встроенных Tcl-команд и переменных. Аргумент -
используется для того, чтобы обозначить конец опций.
Следующий аргумент будет использоваться как имя
интерпретатора, даже если он равен <strong>-safe</strong>.</p>
<p>Команда <strong>interp create</strong> возвращает имя нового
интерпретатора. Имя подчиненного интерпретатора должно быть
уникальным среди подчиненных интерпретаторов его мастера.
Если у мастер-идентификатора уже существует.</p>
</dd>
<dt><strong>interp</strong> <strong>delete</strong> ?<em>path</em>...?</dt>
<dd> Удаляет ноль или больше интерпретаторов с именем
<em>path</em>. Для каждого удаляемого интерпретатора удаляются
также его подчиненные интерпретаторы. Если для одного из
аргументов <em>path</em> интерпретатора с таким именем не
существует, команда генерирует ошибку.
</dd>
<dt><strong>interp</strong> <strong>eval</strong> <em>path</em> <em>arg</em>
?<em>arg</em>...? </dt>
<dd> Команда объединяет все аргументы так же, как команда <a
href=concat.html><strong>concat</strong></a>, а затем исполняет
сформированный скрипт в подчиненном интерпретаторе, заданном
аргументом <em>path</em>. Результат выполнения (включая
информацию об ошибках в переменных <a href=
tclvars.html#errorInfo><strong>errorInfo</strong></a> и <a href=
tclvars.html#errorCode><strong>errorCode</strong></a>, если произошла
ошибка) возвращается в вызывающий интерпретатор.
</dd>
<dt><a name=exists></a><strong>interp</strong> <strong>exists</strong>
<em>path</em></dt>
<dd> Возвращает <strong>1</strong>, если подчиненный интерпретатор с
именем <em>path</em> существует в его мастер-интерпретаторе. В
противном случае возвращает <strong>0</strong>. Если аргумент
<em>path</em> представляет относительное имя, то он ищется в том
интерпретаторе, в котором выполняется команда.
</dd>
<dt><a name=expose></a><strong>interp</strong> <strong>expose</strong>
<em>path</em> <em>hiddenName</em> ?<em>exposedCmdName</em>?</dt>
<dd> Разрешает использование в интерпретаторе <em>path</em>
скрытой команды <em>hiddenName</em> под новым именем
<em>exposedCmdName</em> (в настоящее время поддерживаются только
имена в глобальном пространстве имен, не содержащие
&quot;<strong>::</strong>&quot;). Если обычная (не скрытая) команда
<em>exposedCmdName</em> уже существует, генерируется сообщение
об ошибке. Скрытые команды обсуждаются подробно см. &quot;<a
href=#СКРЫТЫЕ КОМАНДЫ>Скрытые команды</a>&quot;.
</dd>
<dt><a name=hide></a><strong>interp</strong> <strong>hide</strong> <em>path</em>
<em>exposedCmdName</em> ?<em>hiddenCmdName</em>?</dt>
<dd> Запрещает использование в интерпретаторе <em>path</em>
обычной команды <em>exposedCmdName</em> и переименовывает ее в
скрытую команду <em>hiddenCmdName</em> (или в скрытую команду
под старым именем, если новое не было задано). Если скрытая
команда с заданным именем уже существует, команда возвращает
ошибку. В настоящее время <em>exposedCmdName</em> и
<em>hiddenCmdName</em> не могут содержать &quot;<strong>::</strong>&quot;.
Команды, которые должны быть скрыты с помощью <strong>interp
hide</strong>, ищутся только в глобальном пространстве имен, даже
если текущее пространство имен не глобальное. Скрытые команды
обсуждаются подробно ниже (см. &quot;<a href=
#СКРЫТЫЕ КОМАНДЫ>Скрытые команды</a>&quot;).
</dd>
<dt><strong>interp</strong> <strong>hidden</strong> <em>path</em></dt>
<dd>Возвращает список скрытых команд интерпретатора
<em>path</em>.
</dd>
<dt><strong>interp</strong> <strong>invokehidden</strong> <em>path</em>
?<em>-global</em>? <em>hiddenCmdName</em> ?<em>arg</em>...?</dt>
<dd> Вызывает в интерпретаторе <em>path</em> скрытую команду
<em>hiddenCmdName</em> с перечисленными аргументами. Никаких
подстановок или вычислений в аргументах не производится. Если
указана опция <em>-global</em>, скрытая команда выполняется на
глобальном уровне в целевом интерпретаторе. В противном
случае она выполняется в текущем контексте и может
использовать значения локальных переменных и переменных из
вышестоящих стеков. Скрытые команды обсуждаются подробно в
соответствующем разделе ниже.
</dd>
<dt><strong>interp</strong> <strong>issafe</strong> ?<em>path</em>? </dt>
<dd>Возвращает <strong>1</strong>, если интерпретатор <em>path</em>
безопасный, и <strong>0</strong> в противном случае.
</dd>
<dt><strong>interp</strong> <strong>marktrusted</strong> <em>path</em></dt>
<dd>Отмечает интерпретатор <em>path</em> как надежный. Не
раскрывает скрытые команды. Команда <strong>interp marktrusted</strong>
может выполняться только из надежного интерпретатора. Если
интерпретатор <em>path</em> уже надежный, команда не оказывает
никакого воздействия.
</dd>
<dt><strong>interp</strong> <strong>share</strong> <em>srcPath</em> <em>channelId</em>
<em>destPath</em></dt>
<dd>Позволяет разделить канал ввода - вывода <em>channelId</em>
между интерпретаторами <em>srcPath</em> и <em>destPath</em>. Оба
интерпретатора после этого будут иметь одинаковые права на
канал. Каналы ввода - вывода, доступные в интерпретаторе,
автоматически закрываются, когда удаляется интерпретатор.
</dd>
<dt><strong>interp</strong> <strong>slaves</strong> ?<em>path</em>?</dt>
<dd>Возвращает список подчиненных интерпретаторов для
интерпретатора <em>path</em>. Если аргумент <em>path</em>
отсутствует, возвращает список подчиненных интерпретаторов для
интерпретатора, в котором выполняется команда.
</dd>
<dt><strong>interp</strong> <strong>target</strong> <em>path</em> <em>alias</em></dt>
<dd> Возвращает список, описывающий целевой интерпретатор
(интерпретатор, в котором выполняется реальная команда при
вызове команды-алиаса) для алиаса <em>alias</em>. Алиас задается
именем интерпретатора <em>path</em> и команды-алиаса
<em>alias</em> как в команде <strong>interp alias</strong> выше. Имя
целевого интерпретатора возвращается как имя интерпретатора
относительно имени интерпретатора, в котором выполняется
команда. Если это текущий интерпретатор, то возвращается
пустой список. Если этот интерпретатор не является потомком
интерпретатора, в котором выполняется команда, генерируется
ошибка. Реальная команда не обязана быть определена в момент
выполнения данной команды.
</dd>
<dt><strong>interp</strong> <strong>transfer</strong> <em>srcPath</em>
<em>channelId</em> <em>destPath</em> </dt>
<dd>Делает канал ввода - вывода <em>channelId</em> доступным в
интерпретаторе <em>destPath</em> и недоступным в интерпретаторе
<em>srcPath</em>.
</dd>
</dl>
<h2><a name=КОМАНДА РАБОТЫ С ИНТЕРПРЕТАТОРОМ></a>КОМАНДА РАБОТЫ С
ИНТЕРПРЕТАТОРОМ (ПОДЧИНЕННАЯ КОМАНДА)</h2>
<p>Для каждого подчиненного интерпретатора, созданного с помощью
команды <strong>interp</strong>, в мастер-интерпретаторе создается команда
с тем же именем, что и подчиненный интерпретатор. Эта команда
предназначена для выполнения различных операций в подчиненном
интерпретаторе. В общем случае она имеет следующий вид:
</p>
<pre>
slave command ?arg arg...?
</pre>
<p>где <em>slave</em> - имя подчиненного интерпретатора, а
аргументы <em>command</em> и <em>arg</em> <em>arg</em>... определяют
конкретное назначение команды. Ниже перечислены возможные
формы команды.</p>
<dl>
<dt><em>slave</em> <strong>aliases</strong></dt>
<dd>Возвращает список всех алиасов в подчиненном интерпретаторе
<em>slave</em>. Возвращаемые имена - это имена,
использовавшиеся при создании соответствующих алиасов. Они
могут не совпадать с текущими именами команд, если те были
переименованы.
</dd>
<dt> <em>slave</em> <strong>alias</strong> <em>srcCmd</em> </dt>
<dd> Возвращает список, состоящий из имени реальной команды и ее
аргументов, ассоциированных с алиасом <em>srcCmd</em>.
Возвращаются те же значения, что и в команде создания
алиаса. Если созданный алиас был переименован, то в команде
надо указывать имя <em>srcCmd</em>, которое использовалось при
создании алиаса.
</dd>
<dt><em>slave</em> <strong>alias</strong> <em>srcCmd</em> <em>{}</em></dt>
<dd> Удаляет алиас <em>srcCmd</em> в подчиненном интерпретаторе.
Аргумент <em>srcCmd</em> указывает имя алиаса в момент
создания. Если после этого он был переименован, удалится
переименованная команда.
</dd>
<dt> <em>slave</em> <strong>alias</strong> <em>srcCmd</em> <em>targetCmd</em>
?<em>arg</em>..?</dt>
<dd> Эта команда создает команду - алиас в подчиненном
интерпретаторе. Каждый раз, когда в подчиненном интерпретаторе
будет вызываться команда <em>srcCmd</em>, реально выполняться
будет команда <em>targetCmd</em> в
мастер-интерпретаторе. Аргументы <em>arg</em>, если они есть,
определяют дополнительные аргументы для команды
<em>targetCmd</em>, которые будут вставлены перед аргументами,
заданными при вызове <em>srcCmd</em>. Подробнее см. &quot;<a
href=#ИСПОЛЬЗОВАНИЕ АЛИАСОВ>Использование
алиасов</a>&quot;.
</dd>
<dt><em>slave</em> <strong>eval</strong> <em>arg</em> ?<em>arg</em>..?</dt>
<dd>Эта команда объединяет все свои аргументы так же, как
команда <a href=concat.html><strong>concat</strong></a>, и выполняет
сформированный таким образом скрипт в подчиненном
интерпретаторе. Результат выполнения (включая информацию об
ошибках в переменных <a href=tclvars.html#errorInfo>
<strong>errorInfo</strong></a> и <a
href=tclvars.html#errorCode><strong>errorCode</strong></a>, если
произошла ошибка) возвращается в вызывающий интерпретатор.
</dd>
<dt><em>slave</em> <strong>expose</strong> <em>hiddenName</em>
?<em>exposedCmdName</em>?</dt>
<dd> Разрешает использование в подчиненном интерпретаторе
скрытой команды <em>hiddenName</em> под новым именем <em>
exposedCmdName</em> (в настоящее время поддерживаются только
имена в глобальном пространстве имен, не содержащие
&quot;<strong>::</strong>&quot;). Если обычная (не скрытая) команда
<em>exposedCmdName</em> уже существует, генерируется сообщение
об ошибке. Скрытые команды обсуждаются ниже (см. &quot;<a href=
#СКРЫТЫЕ КОМАНДЫ>Скрытые команды</a>&quot;).
</dd>
<dt><em>slave</em> <strong>hide</strong> <em>exposedCmdName</em>
?<em>hiddenCmdName</em>?</dt>
<dd>Запрещает использование в подчиненном интерпретаторе обычной
команды <em>exposedCmdName</em> и переименовывает ее в скрытую
команду <em>hiddenCmdName</em> (или в скрытую команду под старым
именем, если новое не было задано). Если скрытая команда с
заданным именем уже существует, команда возвращает ошибку. В
настоящее время <em>exposedCmdName</em> и <em>hiddenCmdName</em>
не могут содержать &quot;<strong>::</strong>&quot;. Команды, которые
должны быть скрыты с помощью <strong>interp hide</strong>, ищутся только
в глобальном пространстве имен, даже если текущее пространство
имен не глобальное. Скрытые команды обсуждаются ниже
(см. &quot;<a href=#СКРЫТЫЕ КОМАНДЫ>Скрытые
команды</a>&quot;).
</dd>
<dt><em>slave</em> <strong>hidden</strong></dt>
<dd>Возвращает список скрытых команд в подчиненном
интерпретаторе.
</dd>
<dt><em>slave</em> <strong>invokehidden</strong> ?<em>-global</em>?
<em>hiddenName</em> ?<em>arg</em>..?</dt>
<dd> Вызывает в подчиненном интерпретаторе скрытую команду
<em>hiddenCmdName</em> с перечисленными аргументами. Никаких
подстановок или вычислений в аргументах не производится. Если
указана опция <em>-global</em>, скрытая команда выполняется на
глобальном уровне в подчиненном интерпретаторе. В противном
случае она выполняется в текущем контексте и может
использовать значения локальных переменных и переменных из
вышестоящих стеков. Скрытые команды обсуждаются подробно в
соответствующем разделе ниже.
</dd>
<dt><em>slave</em> <strong>issafe</strong></dt>
<dd> Возвращает <strong>1</strong>, если подчиненный интерпретатор
безопасный, и <strong>0</strong> в противном случае.
</dd>
<dt><em>slave</em> <strong>marktrusted</strong></dt>
<dd>Отмечает подчиненный интерпретатор как надежный. Не
раскрывает скрытые команды. Команда может выполняться только
из надежного интерпретатора. Если подчиненный интерпретатор
уже надежный, команда не оказывает никакого воздействия.
</dd>
</dl>
<h2><a name=БЕЗОПАСНЫЕ ИНТЕРПРЕТАТОРЫ></a>
БЕЗОПАСНЫЕ ИНТЕРПРЕТАТОРЫ</h2>
<p> Безопасный интерпретатор - это интерпретатор с ограниченной
функциональностью. Поэтому в нем можно без опасений выполнять
произвольные скрипты, даже написанные вашим злейшим врагом, не
опасаясь нарушить выполнение вашего приложения или испортить
содержимое дисков вашего компьютера. Чтобы обеспечить
безопасность, из таких интерпретаторов удалены определенные
команды и переменные. Например, команда создания файлов на диске
и команда запуска подпроцессов. Тем не менее, в безопасном
интерпретаторе можно обеспечить ограниченный доступ к подобным
командам с помощью механизма алиасов. В результате при
выполнении потенциально опасных команд будут вызываться
специально написанные процедуры в мастер-интерпретаторе, которые
могут тщательно проверять заданные аргументы и позволять
использовать только ограниченный набор средств. Например,
создание файлов может быть разрешено только в ограниченном
наборе подкаталогов, а запуск подпроцессов разрешен только для
ограниченного (и фиксированного) набора хорошо проверенных
программ.
</p>
<p> Чтобы создаваемый интерпретатор был безопасным, необходимо при
его создании указать опцию <strong>-safe</strong>. Кроме того, любой
интерпретатор, созданный из безопасного интерпретатора, также
будет безопасным.
</p>
<p> Безопасный интерпретатор создается со следующим набором
команд:</p>
<table>
<tbody>
<tr>
<td><strong><a href=after.html>after</a></strong></td>
<td><strong><a href=append.html>append</a></strong></td>
<td><strong><a href=array.html>array</a></strong></td>
<td><strong><a href=break.html>break</a></strong></td>
<td><strong><a href=case.html>case</a></strong></td>
</tr>
<tr>
<td><strong><a href=catch.html>catch</a></strong></td>
<td><strong><a href=clock.html>clock</a></strong></td>
<td><strong><a href=concat.html>concat</a></strong></td>
<td><strong><a href=continue.html>continue</a></strong></td>
<td><strong><a href=eof.html>eof</a></strong></td>
</tr>
<tr>
<td><strong><a href=error.html>error</a></strong></td>
<td><strong><a href=eval.html>eval</a></strong></td>
<td><strong><a href=expr.html>expr</a></strong></td>
<td><strong><a href=fblocked.html>fblocked</a></strong></td>
<td><strong><a href=fileevent.html>fileevent</a></strong></td>
</tr>
<tr>
<td><strong><a href=flush.html>flush</a></strong></td>
<td><strong><a href=for.html>for</a></strong></td>
<td><strong><a href=foreach.html>foreach</a></strong></td>
<td><strong><a href=format.html>format</a></strong></td>
<td><strong><a href=gets.html>gets</a></strong></td>
</tr>
<tr>
<td><strong><a href=global.html>global</a></strong></td>
<td><strong><a href=history.html>history</a></strong></td>
<td><strong><a href=if.html>if</a></strong></td>
<td><strong><a href=incr.html>incr</a></strong></td>
<td><strong><a href=info.html>info</a></strong></td>
</tr>
<tr>
<td><strong><a href=interp.html>interp</a></strong></td>
<td><strong><a href=join.html>join</a></strong></td>
<td><strong><a href=lappend.html>lappend</a></strong></td>
<td><strong><a href=lindex.html>lindex</a></strong></td>
<td><strong><a href=linsert.html>linsert</a></strong></td>
</tr>
<tr>
<td><strong><a href=list.html>list</a></strong></td>
<td><strong><a href=llength.html>llength</a></strong></td>
<td><strong><a href=lower.html>lower</a></strong></td>
<td><strong><a href=lrange.html>lrange</a></strong></td>
<td><strong><a href=lreplace.html>lreplace</a></strong></td>
</tr>
<tr>
<td><strong><a href=lsearch.html>lsearch</a></strong></td>
<td><strong><a href=lsort.html>lsort</a></strong></td>
<td><strong><a href=package.html>package</a></strong></td>
<td><strong><a href=pid.html>pid</a></strong></td>
<td><strong><a href=proc.html>proc</a></strong></td>
</tr>
<tr>
<td><strong><a href=puts.html>puts</a></strong></td>
<td><strong><a href=read.html>read</a></strong></td>
<td><strong><a href=rename.html>rename</a></strong></td>
<td><strong><a href=return.html>return</a></strong></td>
<td><strong><a href=scan.html>scan</a></strong></td>
</tr>
<tr>
<td><strong><a href=seek.html>seek</a></strong></td>
<td><strong><a href=seek.html>set</a></strong></td>
<td><strong><a href=split.html>split</a></strong></td>
<td><strong><a href=string.html>string</a></strong></td>
<td><strong><a href=subst.html>subst</a></strong></td>
</tr>
<tr>
<td><strong><a href=switch.html>switch</a></strong></td>
<td><strong><a href=tell.html>tell</a></strong></td>
<td><strong><a href=trace.html>trace</a></strong></td>
<td><strong><a href=unset.html>unset</a></strong></td>
<td><strong><a href=update.html>update</a></strong></td>
</tr>
<tr>
<td><strong><a href=uplevel.html>uplevel</a></strong></td>
<td><strong><a href=upvar.html>upvar</a></strong></td>
<td><strong><a href=vwait.html>vwait</a></strong></td>
<td><strong><a href=while.html>while</a></strong></td>
<td></td>
</tr>
</tbody>
</table>
<p>Следующие команды в безопасном интерпретаторе скрыты:</p>
<table>
<tbody>
<tr>
<td><strong><a href=cd.html>cd</a></strong></td>
<td><strong><a href=exec.html>exec</a></strong></td>
<td><strong><a href=exit.html>exit</a></strong></td>
<td><strong><a href=fconfigure.html>fconfigure</a></strong></td>
</tr>
<tr>
<td><strong><a href=file.html>file</a></strong></td>
<td><strong><a href=glob.html>glob</a></strong></td>
<td><strong><a href=load.html>load</a></strong></td>
<td><strong><a href=open.html>open</a></strong></td>
</tr>
<tr>
<td><strong><a href=pwd.html>pwd</a></strong></td>
<td><strong><a href=socket.html>socket</a></strong></td>
<td><strong><a href=source.html>source</a></strong></td>
<td></td>
</tr>
</tbody>
</table>
<p>Эти команды могут быть созданы заново как Tcl-процедуры или
алиасы или разрешены к использованию с помощью команды <a
href=interp.html#expose><strong>interp expose</strong></a>.</p>
<p>Сверх того, в безопасных интерпретаторах отсутствует массив
<a href=tclvars.html#env><strong>env</strong></a>, содержащий обычно
переменные окружения. Это связано с тем, что в переменных
окружения может храниться конфиденциальная информация.</p>
<p>Расширения, загружаемые в безопасный интерпретатор, также
обладают ограниченной функциональностью. Более подробно эти
вопросы обсуждаются в пп. <a
href=SafeTcl.html><strong>SafeTcl</strong></a> и <a
href=load.html><strong>load</strong></a>.
</p>
<h2><a name=ИСПОЛЬЗОВАНИЕ АЛИАСОВ></a>ИСПОЛЬЗОВАНИЕ
АЛИАСОВ</h2>
<p> Механизм алиасов весьма тщательно спроектирован таким образом,
чтобы он позволял без опасений выполнять ненадежные скрипты в
безопасных подчиненных интерпретаторах, используя для алиасов
проверенные команды в мастер-интерпретаторах. Для обеспечения
безопасности принципиально важно, чтобы информация из
подчиненного интерпретатора никогда не обрабатывалась (то есть
скрипты не исполнялись, и в них не производились подстановки) в
мастер-интерпретаторе. В противном случае всегда будет
оставаться возможность написать такой скрипт для подчиненного
интерпретатора, который выполнил бы произвольные действия в
мастер-интерпретаторе и мог бы нарушить его безопасность.</p>
<p>Когда в подчиненном интерпретаторе вызывается команда-алиас,
необходимые Tcl-подстановки в аргументах выполняются там же, как
для обычной Tcl-команды. После этого аргументы объединяются с
целевой командой и ее аргументами, определенными при создании
алиаса. Так, если команда вызова алиаса имела вид <em>srcCmd
arg1 arg2... argN''</em>, то сформируется команда <em>targetCmd
arg arg... arg arg1 arg2... argN''</em>, где <em>arg
arg... arg</em> - аргументы, указанные при создании
алиаса. После этого сформированная команда выполняется в целевом
интерпретаторе (со сформированным набором аргументов). Если в
целевом интерпретаторе нет команды <em>targetCmd</em>, будет
сгенерирована ошибка. Перед выполнением команды в целевом
интерпретаторе больше никаких подстановок в аргументах
произведено не будет. Команда будет вызвана напрямую, а не через
обычный механизм выполнения. Таким образом, подстановки в каждом
слове команды оказываются выполненными ровно один раз: в
<em>targetCmd</em> и <em>arg... arg</em> - при выполнении команды,
с помощью которой был создан алиас, а в <em>arg1 - argN</em> - при
анализе команды алиаса в соответствующем интерпретаторе.</p>
<p>При написании процедуры <em>targetCmd</em>, которую
предполагается использовать для алиаса в безопасном
интерпретаторе, нужно придерживаться следующего правила.
Недопустимо, чтобы в значениях ее аргументов в теле процедуры
производились подстановки, либо чтобы аргументы были скриптами,
исполняемыми в теле процедуры. Нарушение этого правила дает
возможность подчиненному интерпретатору выполнить произвольный
код в мастер-интерпретаторе и нарушить, таким образом,
безопасность системы.</p>
<h2><a name=СКРЫТЫЕ КОМАНДЫ></a>СКРЫТЫЕ КОМАНДЫ</h2>
<p> Безопасные интерпретаторы существенно ограничивают
функциональные возможности выполняемых в них Tcl-скриптов. С
одной стороны, это позволяет избежать нежелательных последствий
при их исполнении, но, с другой стороны, рано или поздно
возникает насущная необходимость выполнить потенциально опасную
команду в безопасном интерпретаторе. Например, прочитать
дополнительный скрипт с помощью команды <a
href=source.html><strong>source</strong></a>. Или выполнить в
Tk-приложении некоторые команды управления окнами.</p>
<p>Команда <strong>interp</strong> обеспечивает решение этой проблемы с
помощью механизма скрытых команд. Потенциально опасные команды
не удаляются из безопасного интерпретатора, а становятся
скрытыми. При этом их невозможно выполнить из скрипта,
выполняемого &quot;внутри&quot; интерпретатора. Но их можно выполнить
&quot;извне&quot; из любого надежного предка интерпретатора с помощью
команды <strong>interp invoke</strong>. Скрытые и обычные (не скрытые)
команды размещаются в различных пространствах имен. Это
позволяет иметь в одном интерпретаторе скрытую и обычную команды
с одним и тем же именем.</p>
<p>Скрытые команды могут использоваться в теле процедуры,
использованной при определении алиаса. Например, в подчиненном
интерпретаторе можно создать алиас source. Вызываемая при этом
процедура в мастер-интерпретаторе проверяет допустимость
запрошенной операции (например, что запрошенный файл находится в
соответствующем каталоге, к которому разрешен доступ из
подчиненного интерпретатора) и вызывает в подчиненном
интерпретаторе скрытую команду <a
href=source.html><strong>source</strong></a>. Обратите внимание, что
в этом случае в подчиненном интерпретаторе существует две
команды <a href=source.html><strong>source</strong></a>: скрытая и
алиас.</p>
<p>Из мастер-интерпретатора возможен вызов скрытых команд
подчиненного интерпретатора через механизм алиасов. Поэтому в
теле процедур, предназначенных для создания алиаса, необходимо
избегать подстановок и команд исполнения для
аргументов. См. &quot;<a href=
#ИСПОЛЬЗОВАНИЕ АЛИАСОВ>Использование алиасов</a>&quot;.</p>
<p>Безопасные интерпретаторы не могут &quot;изнутри&quot; вызвать скрытую
команду в себе или своих потомках.</p>
<p>Множество скрытых команд может быть изменено из надежного
интерпретатора с помощью команд <a href=#expose><strong>interp
expose</strong></a> и <a href=#hide><strong>interp
hide</strong></a>. Безопасный интерпретатор не может изменить набор
скрытых команд в себе или своих потомках.</p>
<p>В настоящее время имена скрытых команд не могут содержать имени
пространства имен. Поэтому, прежде чем скрыть команду, ее надо
перевести в глобальное пространство имен. Команды, которые
необходимо скрыть, должны находиться в глобальном пространстве
имен. Это позволяет избежать ошибочного скрытия одноименной
команды из другого пространства имен.</p>
</body>
</html>