3cd12006bb
Signed-off-by: Dean Troyer <dtroyer@gmail.com>
140 lines
5.2 KiB
Diff
140 lines
5.2 KiB
Diff
---
|
|
lshell/shellcmd.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++-----
|
|
1 file changed, 71 insertions(+), 6 deletions(-)
|
|
|
|
--- a/lshell/shellcmd.py
|
|
+++ b/lshell/shellcmd.py
|
|
@@ -28,6 +28,7 @@ import readline
|
|
import glob
|
|
import subprocess
|
|
|
|
+from time import gmtime, strftime
|
|
from utils import get_aliases
|
|
|
|
|
|
@@ -50,6 +51,9 @@ class ShellCmd(cmd.Cmd, object):
|
|
else:
|
|
self.stderr = stderr
|
|
|
|
+ # create a devnull device
|
|
+ self.devnull = open(os.devnull, 'w')
|
|
+
|
|
self.args = args
|
|
self.conf = userconf
|
|
self.log = self.conf['logpath']
|
|
@@ -145,13 +149,63 @@ class ShellCmd(cmd.Cmd, object):
|
|
self.g_cmd, self.g_arg, self.g_line = ['', '', '']
|
|
return object.__getattribute__(self, attr)
|
|
|
|
+ def check_prompt(self, var, value):
|
|
+ """ check if user is attempting to
|
|
+ modify shell prompt and if so then
|
|
+ update the prompt
|
|
+ """
|
|
+ if 'PS' in var:
|
|
+ if 'PS1' in var:
|
|
+ # update prompt
|
|
+ self.promptbase = self.setprompt(
|
|
+ {'prompt' : value.strip('\n').strip('\r')})
|
|
+ self.updateprompt(os.getcwd())
|
|
+ else:
|
|
+ self.log.critical("*** forbidden %s prompt change requested. "
|
|
+ "Only PS1 changes permissible" % var)
|
|
+
|
|
+
|
|
def setprompt(self, conf):
|
|
""" set prompt used by the shell
|
|
"""
|
|
if conf.has_key('prompt'):
|
|
promptbase = conf['prompt']
|
|
- promptbase = promptbase.replace('%u', getuser())
|
|
- promptbase = promptbase.replace('%h', os.uname()[1].split('.')[0])
|
|
+ # Recognize shell name control command
|
|
+ promptbase = re.sub(r'\\s', 'lshell',
|
|
+ promptbase)
|
|
+ # Recognize username control command
|
|
+ promptbase = re.sub(r'\\u|%u', getuser(),
|
|
+ promptbase)
|
|
+ # Recognize hostname control command
|
|
+ promptbase = re.sub(r'\\h|%h', os.uname()[1].split('.')[0],
|
|
+ promptbase)
|
|
+ # Recognize full hostname control command
|
|
+ promptbase = re.sub(r'\\H', os.uname()[1],
|
|
+ promptbase)
|
|
+ # Recognize time control commands
|
|
+ promptbase = re.sub(r'\\t', strftime("%H:%M:%S", gmtime()),
|
|
+ promptbase)
|
|
+ promptbase = re.sub(r'\\T', strftime("%I:%M:%S", gmtime()),
|
|
+ promptbase)
|
|
+ promptbase = re.sub(r'\\A', strftime("%H:%M", gmtime()),
|
|
+ promptbase)
|
|
+ promptbase = re.sub(r'\\@', strftime("%I:%M:%S%p", gmtime()),
|
|
+ promptbase)
|
|
+ promptbase = re.sub(r'\\d', strftime("%a %b %d", gmtime()),
|
|
+ promptbase)
|
|
+ ########################################################
|
|
+ # The following control commands are not supported: #
|
|
+ # v - the shell version #
|
|
+ # V - the shell release version #
|
|
+ # w - Complete path of current working directory #
|
|
+ # W - the basename of the current working directory #
|
|
+ # ! - the history number of this command #
|
|
+ # # - the command number of this command #
|
|
+ # $? - status of the last command #
|
|
+ # $() - any command executions #
|
|
+ ########################################################
|
|
+ promptbase = re.sub(r'\\v|\\V|\\w|\\W|\\!|\\#|\\\$\?|\\\$\(.*\)|\\\$', '',
|
|
+ promptbase)
|
|
else:
|
|
promptbase = getuser()
|
|
|
|
@@ -199,7 +253,7 @@ class ShellCmd(cmd.Cmd, object):
|
|
def export(self):
|
|
""" export environment variables """
|
|
# if command contains at least 1 space
|
|
- if self.g_line.count(' '):
|
|
+ if self.g_line.count(' '):
|
|
env = self.g_line.split(" ", 1)[1]
|
|
# if it conatins the equal sign, consider only the first one
|
|
if env.count('='):
|
|
@@ -216,6 +270,10 @@ class ShellCmd(cmd.Cmd, object):
|
|
cin, cout = os.popen2('`which echo` %s' % value)
|
|
value = cout.readlines()[0]
|
|
|
|
+ # check if new exported environment
|
|
+ # is a prompt change command
|
|
+ self.check_prompt(var, value)
|
|
+
|
|
os.environ.update({var: value.rstrip()})
|
|
|
|
def source(self):
|
|
@@ -485,11 +543,14 @@ class ShellCmd(cmd.Cmd, object):
|
|
p = subprocess.Popen( "`which echo` %s" % item,
|
|
shell=True,
|
|
stdin=subprocess.PIPE,
|
|
- stdout=subprocess.PIPE )
|
|
+ stdout=subprocess.PIPE,
|
|
+ stderr = self.devnull )
|
|
(cin, cout) = (p.stdin, p.stdout)
|
|
except ImportError:
|
|
- cin, cout = os.popen2('`which echo` %s' % item)
|
|
- item = cout.readlines()[0].split(' ')[0].strip()
|
|
+ cin, cout = os.popen2('`which echo` %s 2>/dev/null' % item)
|
|
+ shellresponse = cout.readlines()
|
|
+ if shellresponse:
|
|
+ item = shellresponse[0].split(' ')[0].strip()
|
|
item = os.path.expandvars(item)
|
|
tomatch = os.path.realpath(item)
|
|
if os.path.isdir(tomatch) and tomatch[-1] != '/': tomatch += '/'
|
|
@@ -559,6 +620,10 @@ class ShellCmd(cmd.Cmd, object):
|
|
if len(env) is not 2:
|
|
continue
|
|
newenv.update(dict([env]))
|
|
+ # check if the new environment includes
|
|
+ # any Shell prompt change commands
|
|
+ self.check_prompt(env[0], env[1])
|
|
+
|
|
os.environ.update(newenv)
|
|
|
|
def loginCmdParse(self, script):
|