Spec-Zone.ru › Tcl/Tk

exec

ИМЯ
exec — Вызов дочерних процессов
СИНТАКСИС
ОПИСАНИЕ
-ignorestderr
-keepnewline
--
|
|&
< имяФайла
<@ идентификаторФайла
<< значение
> имяФайла
2> имяФайла
>& имяФайла
>> имяФайла
2>> имяФайла
>>& имяФайла
>@ идентификаторФайла
2>@ идентификаторФайла
2>@1
>&@ идентификаторФайла
ПРОБЛЕМЫ ПЕРЕНОСИМОСТИ
Windows (все версии)
Unix (включая Mac OS X)
ПРИМЕРЫ UNIX
РАБОТА С НЕНУЛЕВЫМИ РЕЗУЛЬТАТАМИ
РАБОТА С ЦИТИРОВАННЫМИ АРГУМЕНТАМИ
РАБОТА С ПОДСТАНОВКАМИ
РАБОТА С ФРАГМЕНТАМИ СКРИПТОВ ЧАСТИ SHELL
ПРИМЕРЫ WINDOWS
РАБОТА С ПРОГРАММАМИ КОНСОЛИ
РАБОТА С ВСТРОЕННЫМИ КОМАНДАМИ
РАБОТА С МЕСТНЫМИ ИМЕНАМИ ФАЙЛОВ
СМОТРИТЕ ТАКЖЕ
КЛЮЧЕВЫЕ СЛОВА

Имя

exec — Вызов дочерних процессов

Синтаксис

exec ?переключатели? арг ?арг ...? ?&?

Описание

Эта команда обрабатывает свои аргументы как указание одного или нескольких дочерних процессов для выполнения. Аргументы принимают форму стандартной оболочковой цепочки команд, где каждый арг становится одним словом команды, а каждая отдельная команда становится дочерним процессом.

Если начальные аргументы для exec начинаются с -, то они обрабатываются как переключатели командной строки и не являются частью спецификации цепочки команд. В настоящее время поддерживаются следующие переключатели:

-ignorestderr
Прекращает команду exec от обработки выходных сообщений канала стандартной ошибки цепочки команд как ошибки.
-keepnewline
Сохраняет заключительный символ новой строки в выводе цепочки команд. Обычно заключительный символ новой строки удаляется.
--
Помечает конец переключателей. Аргумент, следующий за этим, будет обрабатываться как первый арг, даже если он начинается с -.

Если арг (или пара арг) имеет один из описанных ниже форм, то он используется командой exec для управления потоком ввода и вывода между дочерними процессами. Такие аргументы не будут переданы дочерним процессам. В формах, таких как “< имяФайла”, имяФайла может быть в отдельном аргументе от “<” или в том же аргументе без промежуточного пробела (т.е. “<имяФайла”).

|
Разделяет отдельные команды в цепочке команд. Стандартный вывод предыдущей команды передается в стандартный ввод следующей команды.
|&
Разделяет отдельные команды в цепочке команд. Как стандартный вывод, так и стандартная ошибка предыдущей команды передаются в стандартный ввод следующей команды. Эта форма перенаправления переопределяет формы, такие как 2> и >&.
< имяФайла
Файл с именем имяФайла открывается и используется как стандартный ввод для первой команды в цепочке команд.
<@ идентификаторФайла
идентификаторФайла должен быть идентификатором открытого файла, например, возвращаемым значением предыдущего вызова open. Он используется в качестве стандартного ввода для первой команды в цепочке команд. идентификаторФайла должен быть открыт для чтения.
<< значение
Значение передается первой команде в качестве стандартного ввода.
> имяФайла
Стандартный вывод последней команды перенаправляется в файл с именем имяФайла, перезаписывая его предыдущее содержимое.
2> имяФайла
Стандартная ошибка всех команд в цепочке команд перенаправляется в файл с именем имяФайла, перезаписывая его предыдущее содержимое.
>& имяФайла
Как стандартный вывод последней команды, так и стандартная ошибка всех команд перенаправляются в файл с именем имяФайла, перезаписывая его предыдущее содержимое.
>> имяФайла
Стандартный вывод последней команды перенаправляется в файл с именем имяФайла, добавляя к нему, а не перезаписывая его.
2>> имяФайла
Стандартная ошибка всех команд в цепочке команд перенаправляется в файл с именем имяФайла, добавляя к нему, а не перезаписывая его.
>>& имяФайла
Как стандартный вывод последней команды, так и стандартная ошибка всех команд перенаправляются в файл с именем имяФайла, добавляя к нему, а не перезаписывая его.
>@ идентификаторФайла
идентификаторФайла должен быть идентификатором открытого файла, например, возвращаемым значением предыдущего вызова open. Стандартный вывод последней команды перенаправляется в файл идентификаторФайла, который должен был быть открыт для записи.
2>@ идентификаторФайла
идентификаторФайла должен быть идентификатором открытого файла, например, возвращаемым значением предыдущего вызова open. Стандартная ошибка всех команд в цепочке команд перенаправляется в файл идентификаторФайла. Файл должен быть открыт для записи.
2>@1
Стандартная ошибка всех команд в цепочке команд перенаправляется в результат команды. Этот оператор допустим только в конце цепочки команд.
>&@ идентификаторФайла
идентификаторФайла должен быть идентификатором открытого файла, например, возвращаемым значением предыдущего вызова open. Как стандартный вывод последней команды, так и стандартная ошибка всех команд перенаправляются в файл идентификаторФайла. Файл должен быть открыт для записи.

Если стандартный вывод не перенаправлен, то команда exec возвращает стандартный вывод последней команды в цепочке команд, если не указан “2>@1”, в этом случае стандартная ошибка также включается. Если какая-либо из команд в цепочке команд завершается аномально или убивается или приостанавливается, то exec вернет ошибку, и сообщение об ошибке будет содержать вывод цепочки команд, за которым следуют сообщения об аномальных завершениях; возвращаемый параметр -errorcode будет содержать дополнительную информацию об последней встреченной аномальной остановке. Если какая-либо из команд записывает в свой файл стандартной ошибки, и эта стандартная ошибка не перенаправлена, и -ignorestderr не указан, то exec вернет ошибку; сообщение об ошибке будет содержать стандартный вывод цепочки команд, за которым следуют сообщения об аномальных завершениях (если таковые имеются), за которым следует вывод стандартной ошибки.

Если последний символ результата или сообщения об ошибке является символом новой строки, то этот символ обычно удаляется из результата или сообщения об ошибке. Это согласуется с другими возвращаемыми значениями Tcl, которые обычно не заканчиваются символами новой строки. Однако, если указан -keepnewline, то заключительный символ новой строки сохраняется.

Если стандартный ввод не перенаправлен с помощью “<”, “<<” или “<@”, то стандартный ввод для первой команды в цепочке команд берется из текущего стандартного ввода приложения.

Если последнее арг — это “&”, то цепочка команд выполняется в фоновом режиме. В этом случае команда exec вернет список, элементы которого — идентификаторы процессов для всех дочерних процессов в цепочке команд. Стандартный вывод последней команды в цепочке команд будет направлен в стандартный вывод приложения, если он не перенаправлен, а вывод ошибок всех команд в цепочке команд будет направлен в файл стандартной ошибки приложения, если он не перенаправлен.

Первое слово в каждой команде принимается как имя команды; выполняется замена тильды в нем, и если результат не содержит слешей, то каталоги в переменной окружения PATH проверяются на наличие исполняемого файла с заданным именем. Если имя содержит слеш, то оно должно указывать на исполняемый файл, доступный из текущего каталога. На аргументы команд не выполняются расширения «glob» или другие подобные оболочке подстановки.

Проблемы переносимости

Windows (все версии)
Чтение из сокета или запись в него, используя обозначение «@ fileId», не работает. При чтении из сокета 16-битное приложение DOS зависнет, а 32-битное — сразу вернёт значение конца файла. При записи в сокет любого типа информация вместо этого отправляется в консоль, если она есть, или отбрасывается.

Текстовый виджет консоли Tk не предоставляет реальные стандартные возможности ввода/вывода. В Tk, при перенаправлении со стандартного ввода, все приложения увидят немедленный конец файла; информация, перенаправляемая в стандартный вывод или стандартную ошибку, будет отброшена.

В качестве разделителей путей для аргументов команд Tcl принимаются как прямые, так и обратные косые черты. При выполнении приложения имя пути, указанное для приложения, также может содержать прямые или обратные косые черты в качестве разделителей путей. Однако имейте в виду, что большинство приложений Windows принимают аргументы с прямыми косыми чертами только как разделители опций и обратные косые черты только в путях. Любые аргументы приложения, указывающие имя пути с прямыми косыми чертами, не будут автоматически преобразованы в использование символа обратной косой черты. Если аргумент содержит прямые косые черты как разделители пути, он может или не может быть распознан как имя пути, в зависимости от программы.

Кроме того, при вызове 16-битного приложения DOS или приложения Windows 3.X все имена путей должны использовать короткий, криптографический формат пути (например, «applba~1.def» вместо «applbakery.default»), который можно получить с помощью команды «атрибуты файла fileName -shortname».

Две или более прямых или обратных косых черт подряд в пути указывают на сетевой путь. Например, простое соединение корневого каталога c:/ с подкаталогом /windows/system даст c://windows/system (две косые черты вместе), что относится к точке монтирования, называемой system на компьютере, называемом windows (и c:/ игнорируется), и не эквивалентно c:/windows/system, которое описывает каталог на текущем компьютере. Для конкатенации компонентов пути следует использовать команду file join.

Обратите внимание, что существуют два основных типа приложений Win32 консоли:

  1. CLI — CommandLine Interface, простой обмен stdio. Например, netstat.exe.
  2. TUI — Textmode User Interface, любое приложение, которое обращается к API консоли для выполнения таких операций, как перемещение курсора, установка цвета текста, обнаружение нажатий клавиш и перемещения мыши и т. д. Примером может служить telnet.exe из Windows 2000. Эти типы приложений не являются распространёнными в среде Windows, но существуют.

exec не будет хорошо работать с приложениями TUI, когда консоль отсутствует, как это делается при запуске приложений в wish. Желательно, чтобы приложения консоли были скрыты и откреплены. Это является заданной ограничением, так как exec хочет общаться через каналы. Расширение Expect решает эту проблему при общении с приложением TUI.

При попытке выполнить приложение exec сначала ищет имя, как оно было указано. Затем, в порядке, .com, .exe, .bat и .cmd добавляются в конец указанного имени, и программа ищет более длинное имя. Если имя каталога не было указано в качестве части имени приложения, следующие каталоги автоматически просматриваются в порядке попытки найти приложение:

  • Каталог, из которого загружался исполняемый файл Tcl.
  • Текущий каталог.
  • Каталог системных файлов Windows NT 32-разрядной системы.
  • Каталог системных файлов Windows NT 16-разрядной системы.
  • Домашний каталог Windows NT.
  • Каталоги, перечисленные в пути.

Для выполнения встроенных команд оболочки, таких как dir и copy, вызывающий должен добавить «cmd.exe /c » перед желаемой командой, так как встроенные команды не реализованы с использованием исполняемых файлов.

Unix (включая Mac OS X)
Команда exec полностью функциональна и работает как описано.

Примеры Unix

Вот несколько примеров использования команды exec в Unix. Для выполнения простой программы и получения её результата:
exec uname -a

Работа с результатами, отличными от нуля

Для выполнения программы, которая может вернуть результат, отличный от нуля, вы должны обернуть вызов exec в catch и проверить содержимое возвращаемого параметра -errorcode, если у вас есть ошибка:
set status 0
if {[catch {exec grep foo bar.txt} results options]} {
    set details [dict get $options -errorcode]
    if {[lindex $details 0] eq "CHILDSTATUS"} {
        set status [lindex $details 2]
    } else {
        # Some other error; regenerate it to let caller handle
        return -options $options -level 0 $results
    }
}

Это проще записать с помощью команды try, поскольку это упрощает ловлю определённых типов ошибок. Это делается с помощью кода такого типа:

try {
    set results [exec grep foo bar.txt]
    set status 0
} trap CHILDSTATUS {results options} {
    set status [lindex [dict get $options -errorcode] 2]
}

Работа с процитированными аргументами

При переводе команды из вызова оболочки Unix следует учитывать, что символы одинарных кавычек не имеют специального значения для Tcl. Таким образом:
awk '{sum += $1} END {print sum}' numbers.list

будет переведено во что-то вроде:

exec awk {{sum += $1} END {print sum}} numbers.list

Работа с подстановкой

Если вы конвертируете вызовы, включающие подстановку оболочки, помните, что Tcl не обрабатывает подстановку или не расширяет её в несколько аргументов по умолчанию. Вместо этого вы должны писать так:
exec ls -l {*}[glob *.tcl]

Работа с фрагментами пользовательских скриптов оболочки

Один полезный метод — предоставить пользователям скрипта возможность указать фрагмент скрипта оболочки для выполнения, которому будет передан некоторый данные на стандартный ввод, созданный программой Tcl. Это распространённая техника использования программы lpr для печати. Наиболее простой способ сделать это — передать скрипт пользователя оболочке пользователя для обработки, так как это избегает множества сложностей с разбором других языков.
set lprScript [get from user...]
set postscriptData [generate somehow...]

exec $env(SHELL) -c $lprScript << $postscriptData

Примеры Windows

Вот несколько примеров использования команды exec в Windows. Для запуска экземпляра notepad для редактирования файла без ожидания завершения редактирования пользователем:
exec notepad myfile.txt &

Для печати текстового файла с помощью notepad:

exec notepad /p myfile.txt

Работа с консольными программами

Если программа вызывает другие программы, как это обычно бывает с компиляторами, то вам может потребоваться прибегнуть к пакетным файлам для скрытия окон консоли, которые иногда появляются:
exec cmp.bat somefile.c -o somefile

С файлом cmp.bat, выглядящим примерно так:

@gcc %1 %2 %3 %4 %5 %6 %7 %8 %9

Работа со встроенными командами

Иногда следует быть осторожным, так как разные программы могут иметь одинаковое имя и находиться на пути. Тогда может случиться, что ввод команды в командной строке DOS найдёт другую программу, чем та же команда, запущенная через exec. Это связано с (документированными) различиями в поведении между exec и пакетными файлами DOS.

В случае сомнений используйте команду auto_execok: она вернёт полный путь к программе, как он виден командой exec. Это особенно относится к случаям, когда вы хотите запустить «внутренние» команды, такие как dir из скрипта Tcl (если вам просто нужно перечислить имена файлов, используйте команду glob.) Для этого используйте следующее:

exec {*}[auto_execok dir] *.tcl

Работа с именами файлов в родном формате

Многие программы в Windows требуют, чтобы аргументы имён файлов передавались с обратными косыми чертами в качестве разделителей путей. Это делается с помощью команды file nativename. Например, чтобы сделать каталог (на NTFS) зашифрованным так, чтобы к нему имел доступ только текущий пользователь, требуется использовать команду CIPHER, как показано ниже:
set secureDir "~/Desktop/Secure Directory"
file mkdir $secureDir
exec CIPHER /e /s:[file nativename $secureDir]

См. также

error, file, open

Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/exec.htm

Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/exec.htm

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API