Shells

Required reading: rc, es

Overview - Bourne Shell

Simplest shell: just run cmd arg arg... - fork, exec in child, wait in parent.

More functionality: file redirection cmd >file - open file as fd 1 in child before exec

Still more functionality: pipes cmd | cmd - create a pipe, run first cmd with pipe on fd 1, run second cmd with other end of pipe on fd 0.

More Bourne arcana: $*, $@, environment variables, macro substitution, if, while, for, ||, &&, "foo $x", 'foo $x', `foo`.

Rc

No reparsing of input. (except explicit eval)

variables as lists

explicit concatenation

multiple input pipes <{cmd} - pass /dev/fd/4 as file name.

syntax more like C, less like Algol

Es - extensible shell

goal is to override functionality cleanly

rewrite input like cmd | cmd2 as %pipe {cmd} {cmd2}.

users can redefine %pipe, etc.

need lexical scoping and let to refer to old values of %pipe

need garbage collection to figure out when functions aren't needed anymore

design principle: provide minimal pieces of functionality along with good default implementations of higher-level functionality, but let users customize these implementations: emacs, exokernel.

Why use shells for programming?

more abstract - higher level

concise syntax

simpler

easier for file manipulation, process manipulation

good

batch programming

portability

interactive development environment

connecting programs together

bad

string and character manipulation (sometimes)

speed

large programs

data structures

some functionality is hidden (e.g., networks, but can use nc instead; guis harder).

shell vs scripting langauges

scripting languages fix data structures, functionality, can now write guis

lost default behaviors that are convenient - manipulation of files, programs, pipes

Unexpected uses of shells

acme juke box player - turn events into command stream

double-indirection: a=5 b=a echo $$b => 5.