Password management - the script
Giorgos Keramidas
keramida at ceid.upatras.gr
Wed Dec 21 17:11:08 EET 2005
On 2005-12-21 14:33, Pavlos Parissis <p_pavlos at freemail.gr> wrote:
> > Αν πάλι βαριέστε να το δείτε μου φένεται απόλυτα φυσιολογική
> > αντίδραση :-)
>
> Αν και δεν έχω ιδέα απο python είπα να κάνω ένα απλό τέστ απο
> περιέργεια , δίνοντας echo "dddd" |python show-pass.py
>
> Password DB
> Don't use this programm if you are not authorized to do so (hit ctrl-C to exit)
>
> ?word, number, +, * >******Bad Command******
> ?word, number, +, * >Traceback (most recent call last):
> File "show-pass.py", line 126, in ?
> cmd=left(raw_input(colst+'?word, number, +, * '+colend+'>').strip(),255)
> EOFError: EOF when reading a line
Γι αυτό εγώ αν έγραφα κάτι σαν 'shell' σε Python, θα ξεκινούσα κάπως έτσι:
1 #!/usr/bin/env python
2
3 import sys
4
5 def shellcmd(s):
6 print "## shellcmd \"" + s + "\""
7 return s
8
9 def main():
10 while True:
11 s = sys.stdin.readline()
12 # When we reach EOF, just quit
13 if not s:
14 return
15 try:
16 s = s.strip().rstrip()
17 shellcmd(s)
18 except ShellCommandError, msg:
19 print "command error: " + msg.strip().rstrip()
20
21 # Start at the main loop of the program.
22 main()
Η main() δεν χρειάζεται να είναι πιο περίπλοκη από ένα απλό:
- read command
- run command
- catch errors
- repeat
Η shellcmd() μπορεί να αρχίσει να μεγαλώνει εύκολα, αν της προσθέσεις
ένα dictionary με keys τα 'commands' και value για κάθε command ένα
implementation function (ή ακόμα καλύτερα ένα stack από implementation
functions, ώστε να μπορείς να κάνεις 'nest'/'overload' την υλοποίηση
κάθε shellcmd απλά κάνοντας append() και pop() τις overloaded
υλοποιήσεις:
Ετσι μπορείς να κάνεις ένα 'shell', του οποίου οι υποστηριζόμενες
εντολές και το τι κάνει η κάθε εντολή μπορεί να είναι εντελώς
επεκτάσιμα.
Κάτι άλλο που μπορεί να βολέψει αν φτιάξεις το shell σου με πιο object
oriented τρόπο (όπου 'objects' είναι τα features κι οι εντολές του)
είναι ότι έτσι θα είναι πιο ξεκάθαρο σε κάθε σημείο ποια είναι τα πιθανά
errors και τι πρέπει να κάνεις γι αυτά.
Ενα κάπως καλύτερο παράδειγμα από shell command-loop είναι αυτό:
1 #!/usr/bin/env python
2
3 import sys
4
5 class ShellInvalidCommand(Exception):
6 def __init__(self, value):
7 self.value = value
8 def __str__(self):
9 return repr(self.value)
10
11 class ShellUnknownCommand(Exception):
12 def __init__(self, value):
13 self.value = value
14 def __str__(self):
15 return repr(self.value)
16
17 class ShellCommandError(Exception):
18 def __init__(self, value):
19 self.value = value
20 def __str__(self):
21 return repr(self.value)
22
23 def cmd_ls(e):
24 print " ls(" + ":".join(e) + ")"
25 return 0
26
27 def shellcmd(s):
28 # All the commands supported by this mini-shell.
29 cmds = {'ls':cmd_ls}
30
31 # Nothing to do, fail.
32 if not s:
33 raise ShellInvalidCommand, "no command string"
34
35 # Split the command string in words, and use the first word as the
36 # command name.
37 words = []
38 try:
39 s = s.expandtabs()
40 words = s.split(' ')
41 except:
42 raise ShellCommandError, s
43 if len(words) < 1:
44 raise ShellCommandError, s
45
46 # Look up the command implementation function in the cmds{} dictionary.
47 try:
48 fptr = cmds[words[0]]
49 except:
50 raise ShellUnknownCommand, s
51
52 # Run the command implementation function.
53 try:
54 print "running " + str(fptr)
55 fptr(words)
56 except:
57 ShellCommandError, s
58 return 0
59
60 def main():
61 while True:
62 sys.stdout.write("pyshell> ")
63 sys.stdout.flush()
64 s = sys.stdin.readline()
65
66 # When we reach EOF, just quit
67 if not s:
68 break
69
70 try:
71 s = s.strip().rstrip()
72 shellcmd(s)
73 except ShellInvalidCommand, e:
74 print "pyshell: invalid shell command: " + str(e)
75 except ShellUnknownCommand, e:
76 print "pyshell: unknown shell command: " + str(e)
77 except ShellCommandError, e:
78 print "pyshell: command execution error: " + str(e)
79 except:
80 print "pyshell: unknown error, aborting"
81 return None
82
83 # When the read-eval-exec loop stops, the shell dies
84 sys.stdout.write("\n")
85 sys.stdout.flush()
86 print "pyshell: exiting."
87 return 0
88
89 # Start at the main loop of the program.
90 main()
Το οποίο όταν το τρέξεις θα δεις κάτι σαν αυτό:
pyshell> foo
pyshell: unknown shell command: 'foo'
pyshell> bar
pyshell: unknown shell command: 'bar'
pyshell> ls
running <function cmd_ls at 0x64bca0>
ls(ls)
pyshell> ls -la foo bar
running <function cmd_ls at 0x64bca0>
ls(ls:-la:foo:bar)
pyshell> ^D
pyshell: exiting.
Πρόσεξε ότι η cmd_ls() παίρνει όντως ένα πίνακα με τα 'words' της
εντολής, οπότε μπορεί να χειριστεί όπως θέλει τα arguments που
πήρε στο prompt.
Πολύ απλοϊκό ως shell, σίγουρα, αλλά μπορείς να κάνεις αρκετά
όμορφα πράγματα με ένα read-eval-exec loop :-)
More information about the Linux-greek-users
mailing list