cmd 是一个用于命令行交互的框架。cmd 内包含一个基类 Cmd ,你需 要在它的基础上扩展自己的类,只实例化 Cmd 并不能完成实质性的工作。
Cmd.cmdloop([intro])
不断地提示用户输入,直到满足一定条件。方法会自动解析用户输入,将首个单词
作为命令,余下的部分当作参数。假如用户输入了命令 foo ,如果对象中定义了
do_foo 的方法,该方法就会被调用。
from cmd import Cmd
class MyCmd(Cmd):
def do_foo(self, *args):
print 'arguments is ' + repr(args)
# do something
return True
mycmd = MyCmd() mycmd.cmdloop()
上面的例子,如果用户输入 foo args 将打印出 arguments is ('args',)
return True 表明命令执行完成,不再继续提示输入,否则会持续提示输入
直到用户关闭窗口。
Cmd 对象支持用户在命令开头加入 ! 或者 ? 来改变行为。
如果命令以 ! 开头,Cmd 对象会将输入分配给 do_shell() 方法(如果定义了该方法)。
from cmd import Cmd
class MyCmd(Cmd):
def do_foo(self, *args):
print 'arguments is ' + repr(args)
# do something
return True
def do_shell(self, line):
print 'with exclamation mark: ' + line
return True
mycmd = MyCmd() mycmd.cmdloop()
上面的代码如果用户输入 ! 后加任何字符,都会调用 do_shell() 方法,即使
是 !foo , 同时 do_foo() 方法会被屏蔽而不被调用。
如果用户命令以 ? 开头,那么 Cmd 对象会调用 do_help() 方法,do_help()
方法从 Cmd 中继承,一般不需要重写。如果用户输入了 ?foo ,do_help()
会先调用 help_foo() 方法,如果 help_foo() 未定义,它会输出 do_foo()
的 docstrings, 如果do_foo() 也没有定义,do_help()会列出所有可能的帮
助主题。
回到第一个例子,如果用户输入 foo 以外的命令会报错,默认的提示是:
*** Unknow syntax: command,比如你输入 ‘bar’ ,会提示 *** Unknow
syntax: bar. 可以通过重新 default() 方法改变这个提示。
Cmd.default(line)
在第一个例子的基础上修改一下:
from cmd import Cmd
class MyCmd(Cmd):
def do_foo(self, *args):
print 'arguments is ' + repr(args)
# do something
def default(self, line):
print 'error: ' + line
mycmd = MyCmd() mycmd.cmdloop()
这样如果你输入 bar 则会提示 error: bar.
如果你需要用户输入的不是一个特定的命令,而是一些不固定的字符(甚至没有字符),
比如需要用户输入用逗号隔开的数字做选择,这时就无法用过 do_*() 来处理了。
Cmd 提供了几个 hook 函数可以处理这种情况。
Cmd.emptyline()
用户输入为空时调用。
Cmd.precmd(line)
precmd() 在用户输入后,输入被分配之前调用。它的返回值会传给 onecmd()
方法。
from cmd import Cmd
class MyCmd(Cmd):
def do_yes(self, *args):
print 'yes, you do.'
return True
def precmd(self, line):
if line == 'yep':
return 'yes'
else:
return line
mycmd = MyCmd() mycmd.cmdloop()
执行上面的代码,用户输入 yep 和 yes 会产生同样的效果。
Cmd.postcmd(stop, line)
postcmd() 在输入被分配之后调用,line 为用户输入(precmd() 的返回,因此不一定
是用户最初的输入)。 stop 用来标识是否需要终止提示输入(这个值其实是 onecmd()
的返回值)。此方法的返回值最终会决定提示是否结束,如果返回 False 会继续提示用户
输入。
Cmd.onecmd()
前面两个方法中都提到了 onecmd(), 因为它起到承上启下的作用,它接受 precmd() 的
返回作为参数,处理完后,将返回值作为 stop 参数传给 postcmd() 方法。将用户输入
解析并分配给相应 do_*() 方法的过程其实就是在这个方法中进行。
Cmd.preloop() / Cmd.postloop()
这两个无需多说,在 loopcmd() 调用之前和之后调用。
Cmd.prompt
从上面的例子可以看到,在用户输入前都有一个 (Cmd) , 可以通过修改 prompt 属性
修改成更优雅的提示,比如 ‘Please Type: ‘。
from cmd import Cmd
class MyCmd(Cmd):
prompt = 'Please Type 1: '
def default(self, line):
return ''
def postcmd(self, stop, line):
if line == '1':
print 'Thanks'
return True
return False
mycmd = MyCmd() mycmd.cmdloop();
除了以上主要方法,cmd 还有一些属性和方法用于 Unix 下特有特征。详见 Referrence
Referrence
- http://docs.python.org/2/library/cmd.html