Step 1 of 5 · Reading · ~3 min
Read
Tokenizing & Parsing
Parsing Redirects
After this lesson your shell separates a command's arguments from its redirections: given the tokens of sort < in.txt >> out.txt 2>err, it reports the argument list sort and three redirections, each with the file descriptor it affects, the operator and the target.
Redirections are not arguments
A program never sees > out.txt. By the time it starts, the shell has already opened the file and wired it to descriptor 1, so the program just writes to "standard output". If your parser leaves the redirection tokens in the argument list, echo hi > out would pass the strings > and out to echo and print them.
The POSIX grammar (Shell Command Language, section 2.7) gives each redirection the same shape:
[n] operator word
n is an optional descriptor number, the operator says what to do, and word is the target. The tokenizer from the first lesson already marked an n that touches its operator as an IO number, so you never have to guess from spacing.
| Operator | Meaning | Default n |
|---|---|---|
< | open the file for reading | 0 |
> | open for writing, truncating | 1 |
>> | open for writing, appending | 1 |
<< and <<- | read a here-document, target is the delimiter | 0 |
>& | make n a copy of another descriptor, target is its number or - | 1 |
<& | the same for an input descriptor | 0 |
Where redirections may appear
Anywhere in the simple command. >out echo hi, echo >out hi and echo hi >out all mean the same thing, and none of them gives echo an argument called out. The parser's rule is mechanical: a redirection operator, with its optional IO number before it, consumes the next token as its target; every other token is an argument. Keep both lists in the order they were typed, because a later lesson applies the redirections left to right and the order changes the result.
Worked trace
Take grep -c error <log.txt 2>/dev/null. The tokenizer yields a word grep, a word -c, a word error, the operator <, a word log.txt, an IO number 2, the operator >, a word /dev/null. The walk appends the first three to the arguments. At < it takes log.txt as the target with the default descriptor 0. At the IO number it remembers 2, then at > it takes /dev/null. Result: three arguments, two redirections.
Errors
An operator with nothing after it, as in cat >, is a syntax error near newline. An operator followed directly by another operator, as in cat > > x, is a syntax error near the second one. Report either with the message form given in the exercise. This lesson only deals with a single simple command, so any other operator (;, &&, a pipe) is also reported as unexpected.
Common mistakes
- Treating the digit in
echo 2 > fas a descriptor. It is an argument; the tokenizer only marks a digit as an IO number when it touches the operator. - Reading the target from the wrong place when the operator and target are stuck together (
>out) or apart (> out). After tokenizing there is no difference. - Forgetting the default descriptor, which depends on the operator: 0 for the input operators, 1 for the output ones.
- Dropping a quoted
">"argument. Quoted, it is a word, not an operator.
Your exercise
The starter tokenizes each line and prints the result; you write the function that splits one command's tokens into arguments and redirections. The most likely mistake is giving every redirection descriptor 1.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…