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
codaz/python/shell_readline_avec_cmd.txt · Last modified: 2010/01/12 13:29 (external edit)