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

Создание задачи на выполнение (sys.task)

Объявление

задача = sys.task(путь_к_исполняемому_файлу [, параметры...])

Параметры

  • путь к исполняемому файлу
    Строка
  • параметры...
    Строка, необязательное переменное число параметров; по умолчанию отсутствуют

Возвращаемое значение

  • задача
    Объект выполняемой задачи, возвращает объект для управления задачей или её выполнения

Методы объекта задачи

МетодПараметрыВозвращаемое значениеОписание
:launch()Запускает задачу асинхронно
:wait_until_exit()Синхронно ждёт завершения задачи и блокирует все потоки до её окончания.
:set_stdin(входной_поток)Канал | строкаЗадаёт входной поток задачи. Параметром могут быть "std", "/dev/null", путь к файлу или объект канала. Вызов после запуска задачи вызовет ошибку
:stdin()Канал | строкаВозвращает входной поток задачи. Возможны "std", "/dev/null", путь к файлу или объект канала
:set_stdout(выходной_поток)Канал | строкаЗадаёт выходной поток задачи. Параметром могут быть "std", "/dev/null", путь к файлу или объект канала. Вызов после запуска задачи вызовет ошибку
:stdout()Канал | строкаВозвращает выходной поток задачи. Возможны "std", "/dev/null", путь к файлу или объект канала
:set_stderr(поток_ошибок)Канал | строкаЗадаёт поток ошибок задачи. Параметром могут быть "std", "/dev/null", путь к файлу или объект канала. Вызов после запуска задачи вызовет ошибку
:stderr()Канал | строкаВозвращает поток ошибок задачи. Возможны "std", "/dev/null", путь к файлу или объект канала
:set_work_dir(каталог)строкаЗадаёт рабочий каталог задачи. Вызов после запуска задачи вызовет ошибку
:work_dir()строкаВозвращает рабочий каталог задачи
:set_env(переменные_окружения)таблицаЗадаёт словарь пар ключ-значение переменных окружения задачи. Вызов после запуска задачи вызовет ошибку
:env()таблицаВозвращает словарь пар ключ-значение переменных окружения задачи
:pid()целое числоВозвращает идентификатор процесса задачи; до запуска задачи возвращает 0
:is_running()логическое значениеПроверяет, выполняется ли задача. Даже если :is_running() вернул false, следует один раз вызвать для задачи :wait_until_exit(), чтобы не допустить появления зомби-процесса
:interrupt()логическое значениеОтправляет основному процессу задачи сигнал прерывания SIGINT
:terminate()логическое значениеОтправляет основному процессу задачи сигнал завершения SIGTERM
:kill()логическое значениеОтправляет всем процессам задачи сигнал принудительного завершения SIGKILL; при сборке объекта задачи операция kill выполняется автоматически
:termination_status()целое числоВозвращает статус завершения задачи; если задача ещё не завершилась, возвращает nil и сообщение об ошибке
:termination_reason()строкаВозвращает причину завершения задачи; если задача ещё не завершилась, возвращает nil и сообщение об ошибке

Методы объекта канала

МетодПараметрыВозвращаемое значениеОписание
:read()строкаЧитает из канала подготовленные данные
:write(данные)строкаЗаписывает данные в канал
:wclose()логическое значение, nil | строкаЗакрывает записывающую сторону канала; при успехе возвращает true, при ошибке — false, сообщение об ошибке
:rclose()логическое значение, nil | строкаЗакрывает читающую сторону канала; при успехе возвращает true, при ошибке — false, сообщение об ошибке

Описание

Создаёт выполняемую задачу и возвращает её объект.
Если не нужно блокировать все потоки в ожидании завершения задачи, можно циклически вызывать :is_running() объекта задачи, проверяя, выполняется ли она; после завершения один раз вызовите :wait_until_exit(), чтобы подтвердить остановку задачи.
Функция доступна в версиях после 20250705

Пример

-- Имитация следующей команды Shell
-- echo "你好世界" | /usr/bin/gzip -fc | /usr/bin/gzip -dfc

local comp_tsk = sys.task(jbroot('/usr/bin/gzip'), '-fc') -- Создание задачи сжатия
local decomp_tsk = sys.task(jbroot('/usr/bin/gzip'), '-dfc') -- Создание задачи распаковки

decomp_tsk:set_stdin(comp_tsk:stdout()) -- Входной поток распаковки — выходной поток сжатия

decomp_tsk:launch() -- Запуск задачи распаковки
comp_tsk:launch() -- Запуск задачи сжатия

comp_tsk:stdin():write("你好世界") -- Запись данных во входной поток задачи сжатия
comp_tsk:stdin():wclose() -- Закрытие записывающей стороны входного потока: ввод завершён

comp_tsk:wait_until_exit() -- Ожидание завершения задачи сжатия
decomp_tsk:wait_until_exit() -- Ожидание завершения задачи распаковки

nLog(decomp_tsk:stdout():read()) -- Чтение выходного потока распаковки; выводится "你好世界"

Пример (вызов Persistence Helper TrollStore для обновления)

local persistence_helper_path = app.bundle_path('com.apple.tips')
if not persistence_helper_path then
nLog('没有检测到 Tips.app,请先从 AppStore 安装 Tips(提示)应用')
return
end
local root_helper_path = persistence_helper_path..'/trollstorehelper'
if file.exists(root_helper_path) ~= 'file' then
nLog('未注入巨魔持久助手到 Tips,请先从 TrollStore -> Settings -> Install Persistence Helper 选择 Tips 注入')
return
end
local tsk = sys.task(root_helper_path, 'refresh')
tsk:launch()
tsk:wait_until_exit()
sys.killall(9, 'SpringBoard', 'backboardd')

Пример (вызов TrollStore для установки/удаления App и перестроения кэша значков)

local function _trollstorehelper(...)
local troll_path = app.bundle_path('com.opa334.TrollStore')
assert(type(troll_path) == 'string', 'TrollStore needs to be installed.')
local tsk = sys.task(troll_path..'/trollstorehelper', ...)
tsk:set_stdin('/dev/null')
tsk:launch()
local outbuf = {}
local errbuf = {}
local function drain_stream(stream, buf)
local data = stream:read('nb')
if data and #data > 0 then
buf[#buf + 1] = data
end
end
while tsk:is_running() do
drain_stream(tsk:stdout(), outbuf)
drain_stream(tsk:stderr(), errbuf)
sys.msleep(100)
end
tsk:wait_until_exit()
drain_stream(tsk:stdout(), outbuf)
drain_stream(tsk:stderr(), errbuf)
if tsk:termination_status() == 0 then
local ret = table.concat(outbuf)
return ret
else
local ret = table.concat(errbuf)
return nil, ret
end
end

--- Установка App с помощью TrollStore
---@param ipapath string путь к пакету установки
---@return string? текст результата установки; при ошибке возвращает nil
---@return string? сообщение об ошибке; при успехе возвращает nil
function troll_install(ipapath)
return _trollstorehelper('install', ipapath)
end

--- Удаление App, установленного TrollStore
---@param bid string идентификатор пакета приложения
---@return string? текст результата удаления; при ошибке возвращает nil
---@return string? сообщение об ошибке; при успехе возвращает nil
function troll_uninstall(bid)
return _trollstorehelper('uninstall', bid)
end

--- Перестроение кэша значков TrollStore; операция может занять некоторое время
---@return string? текст результата перестроения; при ошибке возвращает nil
---@return string? сообщение об ошибке; при успехе возвращает nil
function troll_rebuild_icon_cache()
return _trollstorehelper('refresh-all')
end

-- Пример вызова
nLog(troll_install(XXT_SCRIPTS_PATH..'/TrollDecrypt.tipa')) -- Установка TrollDecrypt
nLog(troll_uninstall('com.fiore.trolldecrypt')) -- Удаление TrollDecrypt
nLog(troll_rebuild_icon_cache()) -- Перестроение кэша значков