/Shell-in-c-with-all-advance-feature

Design and implement a simple, interactive shell program that prompts the user for a command, parses the command, and then executes it with a child process. In your solution you are required to use execv(), which means that you will have to read the PATH environment, then search each directory in the PATH for the command file name that appears on the command line. Goals After this exercise you should:  Understand how a command line shell works.  Understand the commands fork, execv and wait.  Feel comfortable compiling simple C-programs using a Makefile. Makefile https://www.includehelp.com/c-programming-questions/what-is-makefile.aspx Background The shell command line interpreter is an application program that uses the system call interface to implement an operator's console. It exports a character-oriented human-computer interface, and uses the system call interface to invoke OS functions. Every shell has its own language syntax and semantics. In conventional UNIX shells a command line has the form command argument_1 argument_2 ... where the command to be executed is the first word in the command line and the remaining words are arguments expected by that command. The number of arguments depends on the command which is being executed. The shell relies on an important convention to accomplish its task: the command is usually the name of a file that contains an executable program. For example ls and cc are the names of files (stored in /bin on most UNIX-style machines). In a few cases, the command is not a file name, but is actually a command that is implemented within the shell; for example cd is usually implemented within the shell rather than in a file. Since the vast majority of the commands are implemented in files, think of the command as actually being a file name in some directory on the machine. This means that the shell's job is to find the file, prepare the list of parameters for the command, and the cause the command to be executed using the parameters. A shell could use many different strategies to execute the user's computation. However the basic approach used in modern shells is to create a new process to execute any new computation. This idea of creating a new process to execute a computation may seem like overkill, but it has a very important characteristic. When the original process decides to execute a new computation, it protect itself from fatal errors that might arise during that execution. If it did not use a child process to execute the command, a chain of fatal errors could cause the initial process to fail, thus crashing the entire machine. Steps These are the detailed steps any shell should take to accomplish its job (note that the code snippets are just examples; they might not suffice for this assignment, but they should give enough clues): Printing a prompt. There is a default prompt string, sometimes hardcoded into the shell, e.g. > or other. When the shell is started it can look up the name of the machine on which it is running, and prepend it to the standard prompt character, for example, giving a prompt string such as zaagblad>. The shell can also be designed to print the current directory as part of the prompt, meaning that each time the user employs cd the prompt string is redefined. Once the prompt string is determined, the shell prints it to stdout whenever it is ready to accept a command line. For example this function prints a prompt: void printPrompt() { /* Build the prompt string to have the machine name, * current directory, or other desired information. */ promptString = ...; printf("%s ", promptString); } Getting the command line. To get a command line, the shell performs a blocking read operation so that the process that executes the shell will be blocked until the user types a command line in response to the prompt. When the command has been provided by the user (and terminated with a newline character, the command line string is returned to the shell. void readCommand(char *buffer) { /* This code uses any set of I/O functions, such as those in the * stdio library to read the entire command line into the buffer. This * implementation is greatly simplified but it does the job. */ gets(buffer); } Note: do not use gets in your final code. Use man gets to see why. Parsing the command. For this assignment your shell doesn't need to be able to handle pipes or redirections. Finding the file. Before you search for the file you have to figure out whether the command needs to be implemented as an internal command or not. If it is not an internal command, you will have to read the environment variable PATH. These environment variables are typically set when the shell is started, but can be modified on the commandline. The command you have to use for this depends on the shell you are using. The PATH environment variable is an ordered list of absolute pathnames that specifies where the shell should search for command files. If the .login file has a line like: set path=(.:/bin:/usr/bin) the shell will first look in the current directory (since the first pathname is "." for the current directory), then in /bin and finally in /usr/bin. If there is no file with the same name as the command from the command line in any of the specified directories, the shell responds to the user that it is unable to find the command. Your solution needs to parse the PATH variable before it begins reading command lines. This can be done with code like this:

Primary LanguageC

Stargazers

No one’s star this repository yet.