Skip to content

Step 1 of 5 · Reading · ~3 min

Read

Execution & Pipelines

Applying Redirections: open and dup2

After this lesson your shell turns the redirections of a command into the exact open, dup2 and close calls the child must make before it runs the program, in the order typed, and it can say where descriptors 0, 1 and 2 point afterwards. That final picture is what explains why cmd > f 2>&1 and cmd 2>&1 > f behave differently.

A descriptor is a pointer

Each process has a table of small integers. Entry 0 is standard input, 1 standard output, 2 standard error, and each entry points at an open file or the terminal. Redirection never moves data; it changes where entries point. Only two operations are needed:

  • open(file, flags) returns the lowest unused descriptor number and points it at the file.
  • dup2(from, to) makes entry to point wherever from points (closing to first).

From operator to calls

RedirectionCalls
> fopen f for writing, creating and truncating; dup2 the new descriptor onto 1; close the temporary
>> fthe same, but opening in append mode
< fopen f read-only, dup2 onto 0, close the temporary
n> f, n< fthe same with n as the target instead of 1 or 0
n>&m or n<&mone call: dup2(m, n). No file is opened
n>&-close descriptor n

When the open already returns the descriptor number you wanted (for example 3> f into a table where 3 is free), there is nothing to move: dup2 onto itself and a following close would undo the work, so the shell skips both. This is also why closing standard input first, as in <&- > f, makes the open return 0.

Order is the whole story

Redirections are applied strictly left to right, and n>&m copies where m points at that moment.

cmd > out 2>&1     1 -> out, then 2 -> where 1 points now: both go to out
cmd 2>&1 > out     2 -> where 1 points now (the terminal), then 1 -> out:
                   only standard output goes to the file

The second form is one of the most common shell mistakes: the errors still reach the screen. A table of descriptor -> target after the last redirection shows the result at a glance, so your program should print it.

Errors

  • A file opened for reading must exist. If it does not, the shell reports No such file or directory and does not run the command; redirections applied before it have already happened, which is why their calls are still listed.
  • n>&m where m is not open is Bad file descriptor.
  • >&word where the word is neither a number nor - is an ambiguous redirect in this lesson.
  • A syntax error from the parser (a missing target) is reported before any calls.

Worked trace

cmd 3>log 1>&3. The IO number 3 targets descriptor 3. Open log: the lowest free descriptor is 3, which is the target, so no dup2 and no close are needed. Next, 1>&3 points 1 at the same file. The table ends as 0 terminal, 1 log, 2 terminal, 3 log.

Common mistakes

  • Applying 2>&1 as though it were "make 2 follow 1 forever". It copies the current target once.
  • Always emitting dup2 and close after an open, even when the open returned the wanted number.
  • Choosing temporary descriptors from a counter instead of the lowest free number.
  • Forgetting that a closed descriptor 0, 1 or 2 is free for the next open.

Your exercise

The starter reads lines, tokenizes them, extracts the redirections with the parser from lesson three and prints the final table. You write the function that applies the redirections. The most likely mistake is processing 2>&1 before > file when the line says the opposite.

Up nextLogical Operators and Lists: &&, || and ;Execution & Pipelines

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…