# The Ins and Outs of Redirected I/O Loops

The Bourne shell usually runs a loop with redirected input or output in a subshell. For distprompter, this means, among other things:

- Any command inside the loop which reads its standard input will read from the pipe or file redirected to the loop's standard input. That's something you have to pay attention to, because the only command which should read from the file is the read command in line 32. The inputs of other commands inside the loop -- like line 45 -- have to be redirected to read from somewhere other than the loop's standard input.
- In some Bourne shells, using the exit command inside a redirected loop will terminate only the subshell that's running the loop; it will not terminate the script. It's hard to call this a "feature"; I'd call it a bug. See the paragraph below for a workaround. Later versions of Bourne-like shells have fixed this problem, more or less, but my fix should work in all Bourne shells.
- If there's any error inside the loop that should terminate the script, an echo writes an error message to file descriptor 2 (lines 58-59). Error messages from other commands that print errors to their standard error go to the same place. File descriptor 2 is redirected to an error-holding file at the subshell (loop) output (line 63). After the loop ends, if the file has anything in it, that means there was an error -- and the script terminates.
- If you change the value of any shell or environment variables inside the loop, their values outside the loop (after the done command in line 63) will not be changed.

  Although this script doesn't need it, here's the usual fix for that problem. Use another file descriptor, like file descriptor 6, and write variable-setting commands to it. Redirect that file descriptor to a temporary file. Then, use the shell's dot command (`.`) to read the temporary file into the shell outside the loop. For example, to get the value of a variable named varname outside the loop:

            while whatever
            do
                ...
               echo "varname='value'" 1>&6
                ...
            done 6>var_set_file
            . var_set_file