Implementation of a simple shell, xsshWhat is a shell? A process that does command line interpretation Reads a command from standard input (stdin) Executes command corresponding to input line In simple case the shell: Reads a command Forks a child to execute the command Wait for child to complete before reading another command.2What is a shell? A real shell handles: Foreground process groups Background process groups Signals Process pipelines Redirection3The UNIX Shell A shell is a command line interpreter Translates commands typed at a terminal (or in a file) Input is from the terminal (stdin) or file User’s /etc/passwd entry indicates the interactive shell Some Shells Bourne Shell (sh): What some use for shell scripts C-Shell, TC-Shell (csh, tcsh): Typical interactive shell Bash Shell (bash, “GNU Bourne-Again Shell”): Default Linux interactive shell4Shell Scripting Shell Script (Shell Program) A file containing shell commands Used heavily in system administration Scripts in /etc/rc*.d/ are executed during system booting A Tutorial on Scripting: www.ooblick.com/text/sh5Input and Output < File Use File as standard input (stdin) Note: stdin is file descriptor (fd 0) > File Use File as standard output (stdout, fd 1) << Word Read from the current file until end of file or an input line containing Word alone >> File Append stdout to File Command1 | Command2 Create a pipeline Connect stdout of Command1 to stdin of Command26Parameter/Command Substitution ${Parameters} indicates parameter substitution The result of substitution is the value of the parameter e.g., $XX=fooecho $XX # output is null stringecho ${X}X # output is fooX Parameters A Name: A sequence of letters, digits or underscores starting with a letter A Number: $1 is the first command line argument, $2 is the second, etc. (positional parameters) Special Parameters: * @ # ? - $ !7Special Parameters $* Equivalent to "$1 $2 ..." $@ Equivalent to "$1" "$2", ... $# Number of positional parameters $$ Process number of this shell $? Value returned by last executed command in decimal $! Process number of last background command $- Options supplied to shell on invocation or by set8Our simple shell: xssh By developing a shell from the button up we explore the intricacies of: Process creation Process termination Process identification Correct handling of signals (future?)9What will our shell do? Execute built-in commands Execute foreground processes Execute background processes Perform variable substitution before executing command Perform redirection Ignore comments and blank lines Implement optional features?10Built-in commands echo W1 W2 … W1, W2, ... are words Compress consecutive white spaces to a single space quit S Exit shell with exit status S, an integer Real shell allows bg processes to continue; xssh shouldn’t !!! wait P Wait for process P to terminate; If P is omitted, wait for all background processes to terminate11Built-in commands (2) set V Val The shell replaces all occurrences of $V with Val, the value of V unset V Remove given variable Special variables: $$ pid of current process, $? exit status of most recent command $! pid of most recent background process NOTE: All shell variables are environment variables12Built-in commands (3) chdir P Change PWD to P, a pathname (same as cd) Assume $HOME if P is omitted The user must have permission to cd to P or else “permission denied”13Non built-in commands Built-in commands evaluated without fork-exec If first word is not a built-in command: it must be a command found in a directory listed in $PATH Directory names are separated by colon (“:”) Must be evaluated with fork-exec14Strategy What are the requirements? Are there assumptions? What is most critical? What are the risky parts of the project? What are the main data structures? i.e., Abstract data types (data and function members) What is the overall control flow? What system calls/library functions will be needed? Can you sketch the whole project on a sheet of paper? Assume simple implementations of each feature15Risky parts eviron Display the environment variables HOME, PWD, PATH getenv(3) These are the ONLY environment variables The root shell inherits the env vars from its parent They should be automatically passed to any children16Risky parts chdir P Easiest approach Use chdir(2) to actually change directory Use putenv(3) to set PWD chdir(2) only affects the process that calls chdir Can also find where you are by calling getcwd(3) quit S Need to cleanup and wait for background processes17Risky parts wait P Need list/table of background processes Non-builtin commands fork-execvp-wait Variable substitution Should be separable code; i.e., inserted before command processing18Observations All system calls and error-prone library functions should be wrapped E.g. “static inline pid_t Fork(void) {. . .}” in stdinc.h 19Basic Control Flowmain:Initialize;while (get line not EOF) {Break line into words;if (builtin command) do_builtin;else do_nonbuiltin;}do_builtin:if (incorrect #args) { Display msg; return; } // optionalcase command { // or directly call function... chdir,echo,quit,wait,set ...}20Basic Control Flowdo_nonbuiltin:if ((pid=Fork( )) error) ... Error ...if (pid == 0) { // child... execvp code ...exit(0);}Wait for child to
View Full Document