可用 cmd 寫出 mongo、redis-cli 那樣的交互命令行客戶端。支持常用快捷鍵和命令補(bǔ)全提示。
從 Cmd 繼承,然后按需要重寫相關(guān)的方法。比較郁悶的是 Cmd 是 Classic Class,建議用多繼承加個(gè) object 基類,否則無(wú)法使用 super 調(diào)用基類方法。
preloop
cmdloop
precmd 修正命令信息,返回 line。
onecmd 查找并執(zhí)行 do_* 方法。 返回 stop 給 postcmd。
do_* 比如 test 命令,對(duì)應(yīng) do_test。 返回 stop 給 onecmd。
default 沒找到 do_* 或無(wú)法解析的命令,默認(rèn)顯示錯(cuò)誤提示。
emptyline 不輸入命令,直接回車。默認(rèn)重復(fù)上次命名。
do_shell 調(diào)用系統(tǒng)命令。
complete_* 參數(shù)補(bǔ)全。如果沒有對(duì)應(yīng)方法,默認(rèn)調(diào)用 completedefault。
help_* help cmd 或 cmd 顯示具體命令幫助信息 (__doc__)。
do_help help 默認(rèn)顯示全部命令列表,可重寫本方法修改輸出。
postcmd 接收 stop 參數(shù),返回 True 終止 cmdloop 循環(huán)。
postloop
通過(guò)返回 stop 值決定是否繼續(xù) cmdloop 循環(huán)。好在函數(shù)默認(rèn)返回 None,沒必要顯式 return。參數(shù) line 不包括命令串。
相關(guān)屬性:
prompt 命令提示符。
identchars 有效命令字符,默認(rèn)是數(shù)字、字母和下劃線。
lastcmd 最后一條命令。
intro 介紹。
doc_header 命令幫助標(biāo)題。
misc_header 沒找到幫助時(shí)顯示的標(biāo)題。
undoc_header 沒有 __doc__ 時(shí)顯示的標(biāo)題。
ruler 幫助信息分隔線,默認(rèn) "="。
use_rawinput 默認(rèn) True。
示例:
#/usr/bin/env python
#coding=utf-8
from os import popen
from cmd import Cmd
from shlex import split as shsplit
class Shell(Cmd, object):
intro = "TEST shell, version 0.0.0.1"
prompt = "$ "
def default(self, line):
# 退出 (EOF, <ctrl> + d)
if line in ("exit", "quit", "bye", "EOF"):
print "bye..."
return True
# 未知命令
super(Shell, self).default(line)
def do_test(self, line):
# 參數(shù)分割
print shsplit(line)
def complete_test(self, text, line, beginidx, endidx):
# 參數(shù)補(bǔ)全
args = ("a1", "a2", "b1", "b2")
return args if not text else filter(lambda s: s.startswith(text), args)
def do_shell(self, line):
# 系統(tǒng)命令
print popen(line).read()
if __name__ == "__main__":
Shell().cmdloop()
還可以用 code.interact() 嵌入 Python Shell 交互環(huán)境。
shlex 是一個(gè)分割 Unix Shell 命令行參數(shù)的簡(jiǎn)單詞法分析器。
>>> from shlex import split
>>> split("ls -l /usr/local")
['ls', '-l', '/usr/local']
>>> split('test a b "c d"') # 對(duì)引號(hào)參數(shù)的支持
['test', 'a', 'b', 'c d']
如果要將分解的列表還原,可以用 subprocess.list2cmdline。
>>> from subprocess import list2cmdline
>>> args = split('test a b "c d"')
>>> list2cmdline(args)
'test a b "c d"'
復(fù)雜的參數(shù)處理,應(yīng)該使用 argparse。