cmd --- 以列為導向的命令直譯器支援

原始碼:Lib/cmd.py


Cmd 類別提供了一個簡單的架構,用於撰寫列導向的命令直譯器。這類直譯器常用於測試控制工具、管理工具以及日後將包裝於更高階介面的原型中。

class cmd.Cmd(completekey='tab', stdin=None, stdout=None)

Cmd 實例或其子類別實例是一種列導向的直譯器架構。通常沒有必要直接實例化 Cmd 本身;它更適合作為你自己定義的直譯器類別的父類別,讓你能繼承 Cmd 的方法,並封裝動作方法。

可選引數 completekeyreadline 模組中用於自動完成的按鍵名稱;預設為 Tab。若 completekey 不為 Nonereadline 可用,則會自動啟用命令自動完成功能。

預設值 'tab' 會被特殊處理,使其在所有的 readline.backend 中皆代表 Tab 鍵。具體來說,若 readline.backendeditline,則 Cmd 會改用 '^I' 取代 'tab'。請注意,其他值不會有此處理方式,且可能僅能在特定的後端中適用。

可選引數 stdinstdout 用來指定 Cmd 實例或其子類別實例所使用的輸入與輸出檔案物件。若未指定,預設為 sys.stdinsys.stdout

若你希望使用指定的 stdin,請務必將該實例的 use_rawinput 屬性設為 False,否則 stdin 會被忽略。

在 3.13 版的變更: 對於 editlinecompletekey='tab' 會被替換為 '^I'

Cmd 物件

Cmd 實例具有以下方法:

Cmd.cmdloop(intro=None)

重複顯示提示字元、接收輸入、剖析接收到的輸入字串前綴,並派發給動作方法,將其餘部分作為引數傳遞給它們

此可選引數為橫幅或導言字串,會在首次顯示提示字元前輸出(此值會覆寫 intro 類別屬性)。

如果已載入 readline 模組,輸入將自動繼承類似 bash 的歷史紀錄編輯功能(例如 Control-P 可向上捲動至上一個命令,Control-N 向下捲動至下一個命令,Control-F 非破壞性地將游標向右移動,Control-B 非破壞性地將游標向左移動等)。

當輸入為檔案結尾(EOF)時,會傳回字串 'EOF'

直譯器實例僅當存在 do_foo() 方法時,才會識別命令名稱 foo。作為特殊情況,以字元 '?' 開頭的列會被派發至 do_help() 方法;另一個特殊情況是,以字元 '!' 開頭的列會被派發至 do_shell() 方法(若該方法已定義)。

postcmd() 方法回傳真值時,此方法將會結束。傳遞給 postcmd()stop 引數是該命令對應的 do_*() 方法的回傳值。

如果啟用了自動完成,命令的自動完成將會自動執行,而命令引數的自動完成則是透過呼叫 complete_foo() 方法並傳入 textlinebegidxendidx 引數來處理。text 是要比對的字串前綴:所有回傳的符合項都必須以此字串開頭。line 是目前的輸入列(前置空白會被移除),begidxendidx 則分別是前綴字串的起始與結束索引,可用來根據引數所在的位置提供不同的自動完成結果。

Cmd.do_help(arg)

所有 Cmd 的子類別都會繼承預先定義的 do_help() 方法。當此方法接收到引數 'bar' 時,會呼叫對應的 help_bar() 方法;若該方法不存在,則會列印 do_bar() 的說明字串(若有的話)。若未提供任何引數,do_help() 會列出所有可用的說明主題(也就是所有具有對應 help_*() 方法或有說明字串的命令),並且也會列出所有尚未記錄的命令。

Cmd.onecmd(str)

將引數視為在回應提示字元時所輸入的內容來直譯。這個方法可以被覆寫,但通常不需要這麼做;參見 precmd()postcmd() 方法,它們提供實用的執行勾點(hook)。此方法的回傳值是一個旗標,用來指出是否應該停止直譯器對命令的直譯。若有對應 str 命令的 do_*() 方法,則會回傳該方法的回傳值;否則,回傳值將來自 default() 方法。

Cmd.emptyline()

在回應提示字元時輸入空白列,會呼叫此方法。若此方法未被覆寫,則會重復上一次輸入的非空命令。

Cmd.default(line)

當輸入列中的命令前綴無法辨識時,會呼叫此方法。若此方法未被覆寫,則會輸出並回傳錯誤訊息。

Cmd.completedefault(text, line, begidx, endidx)

當沒有對應特定命令的 complete_*() 方法時,會呼叫此方法以完成輸入列。預設會回傳空串列。

Cmd.columnize(list, displaywidth=80)

此方法用來將字串串列顯示為緊湊的欄集合。每一欄的寬度僅足以容納其內容,各欄之間以兩個空格分隔,以提高可讀性。

Cmd.precmd(line)

勾點方法會在直譯命令列 line 前執行,但會在提示字元產生並顯示後才觸發。這個方法在 Cmd 類別中為 stub,預期由子類別覆寫。回傳值會作為 onecmd() 方法所執行的命令;precmd() 的實作可以重寫該命令,或直接回傳未變更的 line

Cmd.postcmd(stop, line)

勾點方法會在命令派發完成後執行。這個方法在 Cmd 類別中為 stub,預期由子類別覆寫。line 是剛剛執行的命令列,而 stop 是一個旗標,用來指出在呼叫 postcmd() 後是否應終止執行;該值即為 onecmd() 方法的回傳值。本方法的回傳值將會更新內部的 stop 旗標;若回傳 false,則會繼續進行直譯。

Cmd.preloop()

cmdloop() 被呼叫時,此勾點方法會執行一次。這個方法在 Cmd 類別中為 stub,預期由子類別覆寫。

Cmd.postloop()

cmdloop() 即將回傳時,此勾點方法會執行一次。這個方法在 Cmd 類別中為 stub,預期由子類別覆寫。

Cmd 子類別的實例包含一些公開的實例變數:

Cmd.prompt

用來請求輸入的提示字元。

Cmd.identchars

可作為命令前綴的字元字串