un exemple simple de shell qui supporte la completion readline avec sauvegarde de l'history.
#!/usr/bin/env python2.4 # Copyright (c) 2004 gab <gab @gcu.info>. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. All advertising materials mentioning features or use of this software # must display the following acknowledgement: # This product includes software developed by gab. # 4. Neither the name of the author nor the names of any co-contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY gab AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL gab OR THE VOICES IN HIS HEAD # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # THE POSSIBILITY OF SUCH DAMAGE. import sys, cmd, readline, os, glob from stat import ST_MODE, S_ISDIR class proutsh(cmd.Cmd): def __init__(self): cmd.Cmd.__init__(self) self.prompt = 'proutsh> ' self.histfile = os.getenv("HOME") + '/.proutsh_history' try: os.stat(self.histfile) except OSError: file(self.histfile, "w").close() readline.read_history_file(self.histfile) # an internal filenames list # listable with 'ls' and modifiable with 'add' and 'del' self.items = [] def emptyline(self): """disable the annoying emptyline repeat""" pass def onecmd(self, line): """catch exceptions generated during a command's execution""" try: cmd.Cmd.onecmd(self, line) except ValueError: com = line.split(" ")[0] self.do_help(com) def complete_items(self, text, line, bidx, eidx): """complete numeric items in the playlist""" return [ str(i) for i in range(0, len(self.items)) ] def do_ls(self, args): """List items in the items list.\nUsage: ls""" for i in range(0, len(self.items)): if args == '' or int(args) == i: print "%d: %s" % (i, self.items[i]) complete_ls = complete_items do_list = do_ls complete_list = complete_items def do_add(self, args): """Add an item to the items list.\nUsage: add <file path or URL>""" if args.find("://") >= 0: self.items.append(args) return files = glob.glob(args) files.sort() for f in files: self.items.append(f) def complete_add(self, text, line, *args): """filesystem based completion. XXX: doesn't work well with filenames containing spaces""" args = line.split() if len(args) > 1: arg = args[1] else: arg = "" dirs = arg.split('/') user_elem = dirs[-1] user_dir = "/".join(dirs[:-1] + ['']) if user_dir == '': user_dir = './' flist = [ f for f in os.listdir(user_dir) if f.startswith(user_elem) ] for i in range(0, len(flist)): if S_ISDIR(os.lstat(user_dir + flist[i])[ST_MODE]): flist[i] += '/' else: flist[i] += ' ' return flist def do_del(self, args): """Delete an item from the items list.\nUsage: del <item index>""" self.items.remove(self.items[int(args)]) complete_del = complete_items def do_flush(self, args): """Delete all items from the items list.\nUsage: flush""" self.items = [] # CLI control def do_history(self, args): """Dump command line history""" for i in range(1, readline.get_current_history_length()): print readline.get_history_item(i) def do_exit(self, args): """Exit shell.\nUsage: exit""" readline.write_history_file(self.histfile) sys.exit(0) def do_EOF(self, args): """Exit shell.\nUsage: ^D""" print self.do_exit(args) if __name__ == '__main__': cli = proutsh() while 1: try: cli.cmdloop() except KeyboardInterrupt: print