Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: THEend8_
INFO1112 - Assignment 1 – mysh Your task is to implement your own, Unix shell! Ultimately, your shell should support the following features: Without further ado, let's break down the main components on how the shell works! Starting and Running the Shell Starting the Shell Starting the shell is simply done by running: The shell expects no additional arguments, and additional arguments are silently ignored. Running the Shell When the shell is running, you will see the prompt that has been set from the PROMPT environment variable, and the user will be able to type in commands to be executed: Effectively, your shell will run infinitely (in an infinite loop), until it is terminated, either by EOF (e.g. Ctrl + D), or if the exit built-in command is run (see here for more details on this). You can think of the shell as an "event- driven" program, where it is waiting for a command input (which will be the event), which it then reacts to. While the prompt is being displayed, there are a couple of extra things to keep in mind: a custom initialisation file, .myshrc , which is formatted as JSON. run and execute any program on the system's PATH define your own custom commands using JSON files support additional quality-of-life features to mimic other Unix shells python3 mysh.py >> If the user enters Ctrl + C, but no command is running (i.e. the prompt is being displayed), Ctrl + C should be silently ignored, and a new prompt should be displayed. If the user inputs a blank command (an empty line, with or without whitespace), the shell should simply display a new prompt. 1 / 21 Syntax and Execution Splitting a Line Into Arguments Like other Unix shells, mysh is a line-based command parser. A user inputs one line at a time, and the line is executed as a command. When we input one line of input, the line is split by whitespace, spaces, tabs, etc. (with an exception, more on this below), with each "word" forming an "argument". For example, the line: can be split into a list of arguments (using Python syntax) as: There is one exception to this: quoted strings (both single and double quotes)! The outer level of quotes are stripped from the quoted string. If a string is inside some quotes, and it includes whitespace, the whitespace is preserved. For example, the below line: will be split as: while the below line: will be split as: Quotes can also be escaped by typing a backslash (\) before the quote character. This means that if you have quoted argument of single or double quotes, and type in the same type of quote character prepended with a backslash (e.g. \" or \' ), it won't be interpreted as a closing quote, but instead, as a quote character – similar to the behaviour of Python. Note If your terminal is terminated by EOF, make sure to print an extra newline character! (Thank you to the students who helped raise this to be compatible with Ed test cases, as this was initially overlooked!) hello there how are you ["hello", "there", "how", "are", "you"] hello there "how are you" 'going today' ["hello", "there", "how are you", "going today"] hello there 'my name is "Sarah"' ["hello", "there", 'my name is "Sarah"'] 2 / 21 For example, the below line: will be split as: Edge cases Error cases my "\"string\"" which 'is \'quoted\'' ["my", '"string"', "which", "is 'quoted'"] Tip The shlex module will be incredibly useful to help parse these strings, and will meet the edge cases below! Please use it! It is valid to have double quotes inside single quotes (as in the above example), and single quotes inside double quotes. It is valid for quotes to be spliced inside of arguments, and can even be next to each other, as long as the outer layer of quotes is stripped out! For example, the line below: should be split as: hello there "quotes are""next to 'each'"-other ["hello", "there", "quotes arenext to 'each'-other"] An unterminated quoted argument should be considered a syntax error by your program and should output an error message to stderr , formatted below. For example, for the line: the program should output: to stderr . line with "unterminated string mysh: syntax error: unterminated quote Note that unterminated quote characters are valid if they are inside quotes of a different type. For example, the line: this is "Tom's PC" 3 / 21 Executing Commands When a line is split, the first "word" is always defined as the name of the command to execute. For example, for the line: will be parsed as: with "sort" being the name of the command (or program) we wish to execute, and ["input.txt", "-o", "output.txt"] being the arguments passed to the "sort" program. The command name will be attempted to be matched to a built-in command (see Built-in Commands for all built-in commands), otherwise, it will execute an executable on the system with this name, either by checking in the system's PATH for a matching executable name, or by executing the executable given by an absolute or relative path. For instance: would execute an executable my_compiled_prog in the current directory of the user. If a valid command is successfully entered, the shell will then execute the command, and wait for it to complete, before displaying the prompt again, and asking the user to input another command. can be validly split as: ["this", "is", "Tom's PC"] sort input.txt -o output.txt ["sort", "input.txt", "-o", "output.txt"] ./my_compiled_prog Tip The info you learn about fork and exec in Week 3 will be very useful for helping to implement the ability to run programs in your shell! You can also find implementations of these system calls as functions in the Python os module.