Как вызывать команды bash из сценария tcl?

Команды Bash доступны из интерактивного сеанса tclsh. Например. в сеансе tclsh вы можете иметь

% ls

вместо

$ exec ls

Однако у вас не может быть сценария tcl, который напрямую вызывает команды bash (т.е. без exec).

Как я могу заставить tclsh распознавать команды bash при интерпретации файлов сценария tcl, как это происходит в интерактивном сеансе?

Я предполагаю, что есть какой-то пакет tcl (или что-то в этом роде), который загружается автоматически при запуске интерактивного сеанса для поддержки прямых вызовов команд bash. Как я могу загрузить его вручную в файлы сценария tcl?


person Vahagn    schedule 07.11.2010    source источник


Ответы (3)


Что здесь происходит, так это то, что unknown proc вызывается, когда вы вводите такую ​​команду, как ls, потому что это не существующая команда tcl, и по умолчанию эта команда проверяет, была ли команда вызвана из интерактивного сеанса и сверху. -level (не косвенно в теле процесса) и проверяет, существует ли имя процесса где-то на пути. Вы можете получить что-то подобное, написав свой собственный proc unknown.

Для хорошего начала изучите вывод

info body unknown
person SingleNegationElimination    schedule 07.11.2010
comment
+1: это начало пути, но я считаю, что это приводит к плохому коду. Лучше иметь exec явные вызовы IMO… - person Donal Fellows; 07.11.2010
comment
@Donal: Да, я согласен. Явный лучше, чем неявный, и я бы никогда не рекомендовал переписывать неизвестный процесс, чтобы сделать это или многое другое, за исключением, возможно, улучшения уже существующей функциональности автозагрузки. - person SingleNegationElimination; 07.11.2010

Если вы хотите, чтобы в ваших сценариях были доступны конкретные утилиты, напишите связующие процедуры:

proc ls args {
    exec {*}[auto_execok ls] {*}$args
}

Это даже будет работать (с очевидной адаптацией) для большинства встроенных оболочек или в Windows. (Справедливости ради следует отметить, что обычно вы не хотите использовать внешний ls; внутренний glob, иногда с дополнительной помощью какого-нибудь file.) Некоторые команды требуют немного больше работы (например, перенаправление ввода так, чтобы он поступал из терминала, с дополнительными <@stdin или </dev/tty; это необходимо для stty на некоторых платформах), но это работает достаточно хорошо.

Однако, если то, о чем вы просите, состоит в том, чтобы иметь произвольное выполнение внешних программ без какого-либо дополнительного кода, чтобы отметить, что они являются внешними, это считается нарушением духа Tcl. Проблема в том, что это значительно усложняет поддержку кода; не очевидно, что вы делаете дорогой вызов вместо того, чтобы использовать что-то (относительно) дешевое, что является внутренним. Вставка exec в этом случае не это обременительно…

person Donal Fellows    schedule 07.11.2010
comment
Возможно, это не только противоречит духу Tcl, но и просто плохое программирование в целом. - person Bryan Oakley; 08.11.2010

Одна вещь, которую вы должны знать, это то, что ls не является командой Bash. Это отдельная утилита. Подсказка о том, как tclsh запускает такие утилиты, содержится прямо в его названии — sh означает «оболочка». Так что это грубый эквивалент Bash в том смысле, что Bash также является оболочкой. Tcl != tclsh, поэтому вы должны использовать exec.

person Dennis Williamson    schedule 07.11.2010