Implementation of a simple shell, xssh
What 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. 2
What is a shell? A real shell handles: Foreground process groups Background process groups Signals Process pipelines Redirection 3
The 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 shell 4
Shell 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/sh 5
Input 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 Command2 6
Parameter/Command Substitution ${Parameters} indicates parameter substitution The result of substitution is the value of the parameter e.g., $X X=foo echo $XX echo ${X}X Parameters # output is null string # output is foox 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: * @ #? - $! 7
Special 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 set 8
Our 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?) 9
What 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? 10
Built-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 terminate 11
Built-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 variables 12
Built-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 13
Non 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-exec 14
Strategy 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 feature 15
Risky 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 children 16
Risky 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 processes 17
Risky 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 processing 18
Observations All system calls and error-prone library functions should be wrapped E.g. static inline pid_t Fork(void) {...} in stdinc.h 19
Basic Control Flow main: Initialize; while (get line not EOF) { Break line into words; if (builtin command) else } do_builtin; do_nonbuiltin; do_builtin: if (incorrect #args) { Display msg; return; } // optional case command { // or directly call function... chdir,echo,quit,wait,set... } 20
Basic Control Flow do_nonbuiltin: if ((pid=fork( )) error)... Error... if (pid == 0) { // child... execvp code... exit(0); } Wait for child to terminate; 21