Создание задачи на выполнение (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()) -- Перестроение кэша значков