程序框架
cmd
可用 cmd 写出 mongo、redis-cli 那样的交互命令行客户端。支持常用快捷键和命令补全提示。
从 Cmd 继承,然后按需要重写相关的方法。比较郁闷的是 Cmd 是 Classic Class,建议用多继承加个 object 基类,否则无法使用 super 调用基类方法。
preloop
cmdloop
precmd 修正命令信息,返回 line。
onecmd 查找并执行 do_* 方法。 返回 stop 给 postcmd。
do_* 比如 test 命令,对应 do_test。 返回 stop 给 onecmd。
default 没找到 do_* 或无法解析的命令,默认显示错误提示。
emptyline 不输入命令,直接回车。默认重复上次命名。
do_shell 调用系统命令。
complete_* 参数补全。如果没有对应方法,默认调用 completedefault。
help_* help cmd 或 cmd 显示具体命令帮助信息 (__doc__)。
do_help help 默认显示全部命令列表,可重写本方法修改输出。
postcmd 接收 stop 参数,返回 True 终止 cmdloop 循环。
postloop
通过返回 stop 值决定是否继续 cmdloop 循环。好在函数默认返回 None,没必要显式 return。参数 line 不包括命令串。
相关属性:
prompt 命令提示符。
identchars 有效命令字符,默认是数字、字母和下划线。
lastcmd 最后一条命令。
intro 介绍。
doc_header 命令帮助标题。
misc_header 没找到帮助时显示的标题。
undoc_header 没有 __doc__ 时显示的标题。
ruler 帮助信息分隔线,默认 "="。
use_rawinput 默认 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):
# 参数分割
print shsplit(line)
def complete_test(self, text, line, beginidx, endidx):
# 参数补全
args = ("a1", "a2", "b1", "b2")
return args if not text else filter(lambda s: s.startswith(text), args)
def do_shell(self, line):
# 系统命令
print popen(line).read()
if __name__ == "__main__":
Shell().cmdloop()
还可以用 code.interact() 嵌入 Python Shell 交互环境。
shlex
shlex 是一个分割 Unix Shell 命令行参数的简单词法分析器。
>>> from shlex import split
>>> split("ls -l /usr/local")
['ls', '-l', '/usr/local']
>>> split('test a b "c d"') # 对引号参数的支持
['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"'
复杂的参数处理,应该使用 argparse。