建立一個執行任務 (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()) -- 讀取解壓任務的輸出流,輸出 "你好世界"
範例(呼叫巨魔持久助手重新整理)
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')
範例(呼叫巨魔安裝卸載 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
--- 使用 TrollStore 安裝一個 App
---@param ipapath string 安裝包路徑
---@return string? 安裝結果文本,失敗返回 nil
---@return string? 錯誤信息,成功返回 nil
function troll_install(ipapath)
return _trollstorehelper('install', ipapath)
end
--- 卸載 TrollStore 安裝的 App
---@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()) -- 重建圖標緩存