A simple console for windows. Any commands that don't make sense as python commands are sent to the system. Fully expandable !! You can reference variables in system commands using %: e.g. echo %fish echoes the contents of the variable fish.........
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | # Idea borrowed from Brian Akey - www.ironkeytech.com/pyshell
# Adapted for Windoze by Fuzzyman
# April 2004
# http://www.voidspace.org.uk/atlantibots/pythonutils.html
import os, sys, os.path
import traceback
from StringIO import StringIO
from traceback import print_exc
def findlocals(line):
"""If a local variable is to be referenced with a system command the variable will be escaped with a $.
This function replaces the variable with it's value.
The $ character can be escaped anywhere with a \ that will be removed.
(a literal '\$' then becomes '\\$')
"""
lpos = line.find(' ')
if lpos == -1: return line # if there's no space (no command) then it's not a variable name
command = line[:lpos]
params = line[lpos:].strip()
escapelist = ['$'] # currently just the $ character
variable = ''
varon = 0
newparams = ''
skip = 0
params += ' ' # so that a variable at the end of a line is terminated
for char in params:
if skip: # was the last characetr a '\'
if char in escapelist: # if the '\' is followed by a '$' it's not a variable - so jsut move on
newparams += char
else:
newparams += '\\' + char
skip = 0
continue
if char == '\\': # is this an escape character ?
skip = 1
continue
if varon: # are we in the process of replacing a variable name
if char == ' ' or char == '\"': # is this the end of the name ?
if globals().has_key(variable):
newparams += str(globals()[variable]) + ' ' # str or repr ??
else:
print 'No such variable as ' + variable
return
varon = 0
variable = ''
else:
variable += char
continue
if char == '$': # have we found the start of a variable name ?
varon = 1
continue
newparams += char
newline = command + ' ' + newparams # rebuild the command line
return newline
def chdir(l1):
"""A simple function to change the directory.
Including handling spaces, quotes etc."""
l2 = l1
if l1[0] == '\"' == l1[-1]: l2 = l1[1:-1]
if os.path.isdir(l2):
os.chdir(l2)
elif os.path.isdir(l2.strip()):
os.chdir(l2.strip())
else:
print 'The system can\'t see directory ' + l1
hist = []
l1 = ''
pt = ' >>> '
quitcom = ['exit', 'x', 'q', 'quit']
credits = """Pyshell for windoze by Fuzzyman.
See http://www.voidspace.org.uk/atlantibots/pythonutils.html"""
print "Welcome to Pyshell for Windoze."
while l1 not in quitcom:
try :
l1 = raw_input(os.getcwd() + pt)
l1 = l1.strip() # note - we lose indentation here... bad if we want to implement functions etc...
if l1.find('$') != -1:
l1 = findlocals(l1) # put in any variables
if not l1: continue
l1 = l1.strip() # same here
hist += [l1]
if l1[0] == '!':
os.system(l1[1:])
elif l1 == 'ls':
os.system('dir')
elif l1 == '?':
print credits
elif l1.startswith('ls '):
os.system('dir ' + l1[3:])
elif l1.startswith('dir ') or l1 == 'dir':
os.system(l1)
elif l1.startswith('echo '):
os.system(l1)
elif l1 == 'hist':
del hist[len(hist)-1]
for h1 in hist:
print h1
elif l1.startswith('cd '):
l1 = l1[3:]
chdir(l1)
elif l1[0] == '/' or l1[0] == '\\':
chdir(l1[1:])
elif l1 == '..':
os.chdir(l1)
else:
try:
exec(l1)
except:
os.system(l1)
except (KeyboardInterrupt, EOFError) : ## ctrl-z or ctrl-c hit
break
except Exception, e:
f = StringIO()
print_exc(file=f)
a = f.getvalue().splitlines()
for line in a:
print line
"""
USAGE
For use on windows systems.
Double click shell.py and it will bring up a console window.
Any of the following commands to exit - 'exit', 'x', 'q', 'quit', ctr-c
'?' brings up a simple credits line.
You can define python variables or expressions - not currently functions - in the usual way.
You can enter system commands in the ususal way.
The command line is first tried as a python command,
if it raises an excpetion it is then tried as a system command.
Single line loops are possible
e.g.
F:\Python Projects\shell >>> for value in [1,2,3,4,5] : print value
1
2
3
4
5
F:\Python Projects\shell >>>
You can insert a python variable (or the string representation of any python object)
into a system command by using $name.
e.g.
F:\Python Projects\shell >>> ls
Volume in drive F is Other Drive
Volume Serial Number is 2446-9C27
Directory of F:\Python Projects\shell
22/04/2004 23:41 <DIR> .
22/04/2004 23:41 <DIR> ..
22/04/2004 23:41 42 filelist.txt
21/04/2004 19:52 <DIR> modules
21/04/2004 20:01 4,450 newshell.py
21/04/2004 14:57 3,347 shell.py
21/04/2004 14:27 109 TODO.txt
4 File(s) 7,948 bytes
3 Dir(s) 116,625,092,608 bytes free
F:\Python Projects\shell >>> source = open('filelist.txt', 'r').readlines()
F:\Python Projects\shell >>> for file in source:print file.strip()
TODO1.txt
TODO2.txt
TODO3.txt
TODO4.txt
F:\Python Projects\shell >>> filename = source[0].strip()
F:\Python Projects\shell >>> echo $filename
TODO1.txt
F:\Python Projects\shell >>>
Any exceptions are displayed (but non-fatal).
EXTRA COMMANDS
If a line starts with a '!' it is always sent to the system. (Useful if a system command clashes with a valid python name).
'ls' is an aliase for 'dir'
lines starting 'echo' are always a system command
'hist' print the current command history
lines starting '/' are passed straight to cd (minus the leading '/')
'..' is an alias for 'cd ..'
Because we are using the os.system command to launch system commands - typing a command like 'help.html' (or any other valid
file) - launches the file with the program the system uses to view that file. In this case it would launch the file 'help.html'
with the system browser.
Can use the import command to run python programs in our namespace.
ISSUES
lowercase - In windoze commands aren't case sensitive - the system commands I've defined are.
No help function
Can't yet put a system command as part of a loop. (or a python function as the parameters to a system command)
No functions, classes or conditionals.
Can only access 'standard' variables through the '$' operator - not lists or dictionaries.
"""
|
Replaces the very basic command shell for windows. Not very complicated - but easily expandable. Allows you to set python variables and then use them in system commands.
Very easy to add extra built in commands...
Prints any exceptions....
Still Buggy. Still a few bugs to sort out in this. I'll do some amendments (e.g. handling quotes in 'cd' commands).
'cd' should work now. Hmm... IPython would be a better console if I could get it working - but this is ok - slight improvement over the windoze console.
pretty good... I've always wanted something like this but never got around to making it. Thanks! I only have 2 suggestions:
1.) For those with cygwin installed it doesnt make sense that "ls" runs "dir", it was easy enough for me to change the code, but it's up to you if you want to keep it that way
2.) one of the most important features (to me at least) in a command line interface is filename completion, something like the functionality from http://www.morearty.com/filec/ would be excellent
thanks again for such a cool program, i'm sure i'll get some use out of it
Changed Again. I've fixed a couple of minor problems with the variables (coping with quotes and I was adding an extra space).
I'll look at filename completion - although I might need to move to a Tkinter window rather than a standard console window to achieve that.