Step 1 of 5 · Reading · ~3 min
Read
Production Concerns
Capstone: The Whole Shell
After this lesson one program does what every earlier lesson did, in the right order: it expands variables, splits quoted input into words, expands wildcards, wires pipelines and redirections, runs the commands that must change the shell itself, and prints a plan for everything else. The tests here send lines that need several stages at once, because that is what "I built a shell" has to mean.
The pipeline, start to finish
One typed line goes through the stages in a fixed order:
| Stage | What happens | Lesson |
|---|---|---|
| Tokenize | quotes, backslashes, operators, IO numbers, comments | 1 |
| Parameter expansion | $NAME, ${NAME} and $? become text | 6 |
| Field splitting | unquoted expansion results split at spaces and tabs | 8 |
| Pathname expansion | unquoted wildcards become sorted matches | 7 |
| Split | the pipe operator cuts the line into pipeline stages | 2 |
| Redirections | each stage's <, >, >>, >& are applied left to right | 3, 11 |
| Execute | builtins in the shell, everything else in a child | 4, 9, 10 |
In this lesson the first three happen inside the starter's lexer, because the shell must know which characters were quoted while it is still reading them.
Three rules the order creates
Expansion cannot create syntax. If X='a|b', then echo $X passes the single word a|b; the bar was never a token. Likewise a wildcard that came out of a variable is still expanded (P='*.c'; ls $P) but one that was quoted, or written as \*, is not.
A word that expands to nothing disappears: cmd $EMPTY x has two words. Only a quoted empty string, "", survives as an empty argument.
An assignment word such as NAME=value sets a shell variable. Its value is not field-split, so Y=$X keeps spaces intact.
Builtins and where they run
cd, exit, unset and assignments change the shell, so they must run in the shell. That holds only when the command is alone: as one stage of a pipeline, or with redirections, a command runs in a child, and cd /tmp | cat leaves the working directory unchanged. Your planner must therefore treat a builtin in a pipeline like any program.
The plan lines
For every stage of a pipeline of n commands print:
RUN <i>/<n> [word] [word] ... in=<..> out=<..> err=<..>
Each descriptor starts as - for the terminal, with standard input pipe for every stage after the first and standard output pipe for every stage before the last. Redirections change the table in order: file:<name>, append:<name>, a copy of another descriptor, or closed. Because the table is updated step by step, 2>&1 >f and >f 2>&1 differ, exactly as in the earlier lesson.
Common mistakes
- Expanding globs before quote removal, so quoted wildcards still match.
- Running
cdfor a stage of a pipeline. - Applying a redirection target through glob expansion.
- Keeping a word that expanded to nothing, or dropping a quoted empty one.
Your exercise
The starter reads FILE lines (files relative to /home/user) and commands, and supplies the lexer, the wildcard matcher and the file system. You write run_line: pipeline splitting, assignments, builtins, redirection and the plan. The most likely mistake is running cd when it is only one stage of a pipeline.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…