Exemple #1
0
    def do_cd(self, line):
        #error handling ensures wrong directory path or permission denial will not crash shell
        try:
            if self.home in line:
                os.chdir('/' + line)
            else:
                os.chdir(os.getcwd() + '/' + line)

        except FileNotFoundError:
            print(Colours.red("Invalid directory: {}".format(line)))

        except Exception as e:
            print(e)

        #update the prompt to show the new directory
        cmd.Cmd.prompt = Colours.cyan('(KarlShell:') + Colours.pink(
            os.getcwd() + ') ')
Exemple #2
0
class MyShell(cmd.Cmd):
    shell = os.environ['PWD']
    cmd.Cmd.intro = "Hello and welcome to KarlShell! (V1.3.1 running from {})".format(
        shell)
    cmd.Cmd.prompt = Colours.cyan('(KarlShell:') + Colours.pink(os.getcwd() +
                                                                ') ')

    dirs = os.getcwd().split('/')
    home = dirs[1]

    #changes the directory
    #is designed to take either the full path starting from the home directory e.g. /home/user/Documents, or take a single subdirectory of the cwd e.g. /Documents
    def do_cd(self, line):
        #error handling ensures wrong directory path or permission denial will not crash shell
        try:
            if self.home in line:
                os.chdir('/' + line)
            else:
                os.chdir(os.getcwd() + '/' + line)

        except FileNotFoundError:
            print(Colours.red("Invalid directory: {}".format(line)))

        except Exception as e:
            print(e)

        #update the prompt to show the new directory
        cmd.Cmd.prompt = Colours.cyan('(KarlShell:') + Colours.pink(
            os.getcwd() + ') ')

    #displays current working directory
    def do_pwd(self, line):
        print(os.getcwd())

    #lists and displays all subdirectories and files
    # if redirect is True, pass output onto output_redirect method
    def do_dir(self, line):
        if self.check_redirect(line) == False:
            print("\n".join(os.listdir()))
        else:
            out = ("\n".join(os.listdir()))
            self.output_redirect(line, out)

    #lists and displays environmental strings
    def do_environ(self, line):
        if self.check_redirect(line) == False:
            for k, v in os.environ.items():
                print(k + ": " + v)
        else:
            out = []
            for k, v in os.environ.items():
                out.append(k + ": " + v)
            out = "\n".join(out)
            self.output_redirect(line, out)

    #outputs the argument supplied by user
    def do_echo(self, line):
        tokens = self.get_tokens(line)
        if self.check_redirect(line) == False:
            print(line + '\n')
        else:
            out = (' '.join(tokens[0:-2]))
            self.output_redirect(line, out)

    #opens manual located in readme file and displays to user twenty lines at a time
    def do_help(self, line):
        try:
            if self.check_redirect(line) == False:
                with open(self.shell + "/readme", "r") as f:
                    i = 2
                    j = 22
                    help_lines = f.read().split("\n")
                    next_twenty = '\n'.join(help_lines[i:j])
                    while j < len(help_lines):
                        next_twenty = '\n'.join(help_lines[i:j])
                        print(next_twenty)
                        input()
                        i += 20
                        j += 20
            else:
                with open(self.shell + "/readme", "r") as f:
                    out = f.read()
                self.output_redirect(line, out)
        except:
            (print("There appears to be a problem with the help manual..."))

    #clears the display by checking terminal size and printing new lines
    def do_clr(self, line):
        rows, columns = os.popen('stty size', 'r').read().split()
        for i in range(0, int(rows)):
            print("\n")

    #pauses operation of the shell until enter is pressed
    def do_pause(self, line):
        input("Press enter to resume..." + "\n")

    #an extra internal command I added to help with testing
    def do_sleep(self, line):
        try:
            time.sleep(int(line))
        except:
            print("Exception!")

    #exits the shell
    def do_quit(self, line):
        sys.exit()

    #default action for when user inputs an empty line
    def emptyline(self):
        print("")

    #default action for commands that are not defined
    def default(self, line):
        tokens = self.get_tokens(line)
        if tokens[-1] == "&":
            self.background_exec(line)
        else:
            self.invoke(line)

    #if user enters a command that is not among the internal commands, check if the command is invocation of external programs and execute them
    def invoke(self, line):
        line = self.get_tokens(line)
        pid = os.fork()

        if pid > 0:
            wait_pid = os.waitpid(pid, 0)
        else:
            try:
                os.execvp(line[0], line)
            except FileNotFoundError:
                print(
                    Colours.red(
                        " '{}' not found. Type 'help' for shell documentation."
                        .format(' '.join(line))))
                self.do_quit('')
            except:
                print("Exception!")
                self.do_quit('')

    #execute program defined in line as background process
    def background_exec(self, line):
        line = self.get_tokens(line)
        subprocess.Popen(line)

    #check if user is attempting to redirect output
    def check_redirect(self, line):
        tokens = self.get_tokens(line)
        if len(tokens) > 0 and (">" in tokens or ">>" in tokens):
            return True
        else:
            return False

    #determine whether user wants to append or truncate and find position of new file name
    def output_redirect(self, line, output):
        tokens = self.get_tokens(line)
        i = 0
        while i < len(tokens) and (tokens[i - 1] != ">"
                                   or tokens[i - 1] != ">>"):
            if tokens[i] == ">":
                self.truncate(line, output, i)
            elif tokens[i] == ">>":
                self.append(line, output, i)
            i += 1

    #get name of new file by using position supplied by output_redirect, and either create new file or truncate existing
    def truncate(self, line, output, position):
        i = position
        tokens = self.get_tokens(line)
        with open(tokens[i + 1], "w") as f:
            f.write(output)

    #same as truncate method, except append to existing file
    def append(self, line, output, position):
        i = position
        tokens = self.get_tokens(line)
        with open(tokens[i + 1], "a") as f:
            f.write("\n" + output)

#a simple method for splitting a line into tokens

    def get_tokens(self, line):
        tokens = line.split()
        return tokens