Это потому, что когда событие запускается, связанный с ним скрипт получает eval
значение на глобальном уровне (согласно bind
руководство ).То есть в случае вашей привязки <Return>
скрипт myOk $cmd ; break
будет выполняться буквально.Следовательно, если в глобальном пространстве имен не существует переменной с именем «cmd» во время выполнения сценария, будет показана ошибка, которую вы показали.
Чтобы устранить проблему, существует несколько способов:
- Выполнить подстановку
$cmd
во время создания и привязки сценария.Чтобы сделать это, просто замените {} на «», чтобы разрешить подстановку переменных, то есть, если вы напишите bind .$cmd <Return> " myOk $cmd ; break "
, связанный скрипт будет myOK hello ; break
- Превратите скрипт обратного вызова в вызов процедуры ипередайте ему явные параметры, например:
bind .$cmd <Return> [list mycallback $cmd]
, а затем убедитесь, что вы определили mycallback
процедуру, принимающую один параметр.Таким образом, вы можете написать универсальные обработчики событий, которые будут параметризованы любыми параметрами, которые вам нужны во время привязки. - Используйте
namespace code
или аналогичный инструмент, чтобы ваш скрипт выполнялся в указанном пространстве имен с указаннымпеременная определена.
Во всех случаях имейте в виду, что, поскольку ваш $ cmd может в некоторых случаях расширяться до чего-то странного, хорошая идея защитить весь сценарий от такой ситуации - вот что [list ...]
делает во втором примере (см. this для получения дополнительной информации).