Questions: Shell Execution Model and Command Processing
5 questions to test your understanding
Score: 0 / 5
Question 1 Multiple Choice
When you run `sort < input.txt > output.txt`, which entity actually opens the files and connects them to the process's stdin and stdout?
AThe sort program reads the redirection syntax and opens the files itself
BThe shell opens the files and connects them to file descriptors in the child process before calling exec
CThe kernel parses the redirection operators and routes I/O automatically
DThe shell passes the filenames as command-line arguments to sort
The shell handles all redirection setup. After forking a child process, the shell (in the child) opens input.txt and connects it to file descriptor 0 (stdin), opens output.txt and connects it to file descriptor 1 (stdout), *then* calls exec to replace the child with sort. The sort program simply reads from stdin and writes to stdout — it has no knowledge of any redirection. This is why redirection works with any program, even those with no awareness of it.
Question 2 Multiple Choice
In the pipeline `cmd1 | cmd2 | cmd3`, when does cmd1 begin executing relative to cmd2 and cmd3?
Acmd1 runs to completion, then its output is passed to cmd2, which runs to completion, then cmd3 runs
BAll three commands are forked and run concurrently, connected by pipes the shell created
CThe shell runs cmd1 in the foreground and cmd2, cmd3 in the background sequentially
Dcmd3 starts first to prepare its input buffer, then cmd2, then cmd1
Pipeline commands run concurrently. The shell creates the pipes, forks all three processes, wires their file descriptors to the appropriate pipe endpoints, and lets them all run simultaneously. The kernel buffers data as needed: cmd1 writes, cmd2 reads and writes, cmd3 reads. This concurrency is what makes pipelines efficient — cmd2 can start processing cmd1's output before cmd1 has finished. Option A (sequential execution) is the most common misconception about pipeline behavior.
Question 3 True / False
Variable expansion (e.g., $HOME) and glob expansion (e.g., *.txt) happen inside the child process after exec() is called.
TTrue
FFalse
Answer: False
All expansion happens in the shell process *before* fork. The shell substitutes $HOME with its value, expands *.txt to the matching list of filenames, and processes command substitutions, all before creating any child process. The child receives only the final, expanded arguments. This is why quoting matters: `echo '$HOME'` suppresses expansion and the child sees the literal string, while `echo "$HOME"` allows it and the child sees the expanded value.
Question 4 True / False
A child process created by the shell inherits its parent's open file descriptors, including stdin, stdout, and stderr.
TTrue
FFalse
Answer: True
Fork creates a nearly identical copy of the parent process, including its open file descriptor table. The child inherits all open file descriptors from the shell — including stdin (0), stdout (1), and stderr (2). This inheritance is what makes redirection possible: the shell can modify these file descriptors in the child *after fork but before exec*, and those modifications persist through the exec call. The executed program starts with whatever file descriptors the shell set up.
Question 5 Short Answer
Explain why quoting matters in shell commands. What specific shell behavior does quoting control, and what problem does it prevent?
Think about your answer, then reveal below.
Model answer: Quoting controls which expansions the shell performs before passing arguments to the child program. Single quotes suppress all expansion; double quotes suppress glob expansion but allow variable and command substitution. Without quoting, a filename containing spaces becomes multiple arguments, and a variable containing spaces splits on whitespace into multiple words. Quoting prevents word splitting and glob expansion from corrupting arguments that should be passed as single units.
The shell performs expansion and word splitting before fork, so the child program receives the results. If a variable contains spaces and is unquoted, the shell splits it into multiple arguments — the program sees more arguments than intended. If a glob pattern is unquoted and matches no files, it may be passed as a literal string or cause an error. Quoting signals to the shell: 'treat this as one unit, don't expand or split it.'