integ/base/lshell/files/lshell-prompt-change-support.patch
Dean Troyer 3cd12006bb StarlingX open source release updates
Signed-off-by: Dean Troyer <dtroyer@gmail.com>
2018-05-31 07:36:35 -07:00

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):