Перейти к содержимому

Выполнение команд

Запуск внешних команд и shell-скриптов с полным контролем над потоками ввода-вывода.

Настройка исполнителей описана в разделе Исполнитель команд.

local exec = require("exec")

Получите ресурс исполнителя по его идентификатору:

local executor, err = exec.get("app:exec")
if err then
return nil, err
end
-- Работа с исполнителем
local proc = executor:exec("ls -la")
-- ...
-- Освобождение ресурса
executor:release()
ПараметрТипОписание
idstringИдентификатор ресурса

Возвращает: Executor, error

Создайте процесс с заданной командой:

-- Простая команда
local proc, err = executor:exec("echo 'Hello, World!'")
-- С рабочей директорией
local proc = executor:exec("npm install", {
work_dir = "/app/project"
})
-- С переменными окружения
local proc = executor:exec("python script.py", {
work_dir = "/scripts",
env = {
PYTHONPATH = "/app/lib",
DEBUG = "true",
API_KEY = api_key
}
})
-- Запуск shell-скрипта
local proc = executor:exec("./deploy.sh production", {
work_dir = "/app/scripts",
env = {
DEPLOY_ENV = "production"
}
})
ПараметрТипОписание
cmdstringКоманда для выполнения
options.work_dirstringРабочая директория
options.envtableПеременные окружения

Возвращает: Process, error

Запуск процесса и ожидание завершения:

local proc = executor:exec("./build.sh")
local ok, err = proc:start()
if err then
return nil, err
end
local exit_code, err = proc:wait()
if err then
return nil, err
end
if exit_code ~= 0 then
return nil, errors.new("INTERNAL", "Сборка завершилась с кодом: " .. exit_code)
end

Получение потоков для чтения вывода процесса:

local proc = executor:exec("./process-data.sh")
local stdout = proc:stdout_stream()
local stderr = proc:stderr_stream()
proc:start()
-- Чтение всего stdout
local output = {}
while true do
local chunk = stdout:read(4096)
if not chunk then break end
table.insert(output, chunk)
end
local result = table.concat(output)
-- Проверка ошибок
local err_output = {}
while true do
local chunk = stderr:read(4096)
if not chunk then break end
table.insert(err_output, chunk)
end
local exit_code = proc:wait()
stdout:close()
stderr:close()
if exit_code ~= 0 then
return nil, errors.new("INTERNAL", table.concat(err_output))
end
return result

Запись данных в stdin процесса:

-- Передача данных команде
local proc = executor:exec("sort")
local stdout = proc:stdout_stream()
proc:start()
-- Запись входных данных
proc:write_stdin("banana\napple\ncherry\n")
proc:write_stdin("") -- Сигнал EOF
-- Чтение отсортированного вывода
local sorted = stdout:read()
print(sorted) -- "apple\nbanana\ncherry\n"
proc:wait()
stdout:close()

Отправка сигналов или закрытие процесса:

local proc = executor:exec("./long-running-server.sh")
proc:start()
-- ... позже, нужно остановить ...
-- Мягкое завершение (SIGTERM)
proc:close()
-- Или принудительное завершение (SIGKILL)
proc:close(true)
-- Или отправка конкретного сигнала
local SIGINT = 2
proc:signal(SIGINT)

Операции exec подчиняются политикам безопасности.

ДействиеРесурсОписание
exec.getID исполнителяПолучение ресурса исполнителя
exec.runКомандаВыполнение конкретной команды
СитуацияТипПовтор
Неверный IDerrors.INVALIDнет
Доступ запрещёнerrors.INVALIDнет
Процесс закрытerrors.INVALIDнет
Процесс не запущенerrors.INVALIDнет
Процесс уже запущенerrors.INVALIDнет

Подробнее см. Обработка ошибок.