Hi Mike, > Actually all shells that I know of don't specify that redirection take > place at the end of the command line. Witness: > > $ <<<$HOME cat > /home/mbianchi > > $ <<<$HOME >/tmp/i cat > $ cat /tmp/i > /home/mbianchi
Well, with caveats; you've got a `simple' command there. The Bourne-shell types all specify that the effect of the redirections is as if their action takes place in sequence. That's why these differ. $ ls -d . missing >foo 2>&1 $ cat foo ls: cannot access missing: No such file or directory . $ ls -d . missing 2>&1 >foo ls: cannot access missing: No such file or directory $ cat foo . $ I point out <foo sort | ... is possible to those that protest cat foo | sort is better in production scripts because it's "more clear". But then I also point out that convention is good and deviating from it slows the careful reader who wonders why it's been done and what might really have been intended, e.g. did the author know that order can be significant. > For instance > > <infile >outfile while read a > do > process ${a} > done That should't work AIUI, and it doesn't here. Re-direction forms part of the `list' that forms the `meat' of the various control structures, e.g. `if list; then...'. IOW, it can occur anywhere inside a `simple command' or at the end of a `command'. The `while' is a reserved word and is part of the grammar outside of the list, so it must come first otherwise it's taken to be the name of a command and hunted through PATH like normal. $ <foo while : while: command not found $ $ <foo if : if: command not found $ And while <infile >outfile read a; do process $a done probably isn't doing what's intended either. The redirection occurs for each run of the loop's condition; IOW, read always reads the first line of infile and, if there's at least one line, always succeeds. Similarly, outfile gets truncated at every turn. The redirections only apply to the condition; the body operates without them in place. That leaves us with putting them at the end of `command' when it's not a `simple command'. while read a; do process $a done <infile >outfile Just as convention has it. ;-) Aside, read's -r option can be useful most of the time unless you want backslashes to be potentially significant. $ read a b c 1\ 2 3 4 5 $ echo $b 3 $ > Sidebar: I always use ${a} instead of $a so they standout more in > the scripts, for readability. And I always strip them out, disliking the noisy syntax that's slower to read carefully and suggesting that something else may have been intended. To each their own. :-) > I wonder sometimes if anyone really understands _all_ of bash(1) . Repeated readings of bash(1) work over time. Especially if all readline material is ignored. Just as learning Perl from perl(1) was possible when it was a single man page. > You know, the original sh had a way to do 1 "here document" at the > end of a shell script? > > ⋮ > cat >outfile > content > more content > ⋮ > > in a shell script file would cat the content, down to the end of the > file, into outfile just as if you were typing it at a terminal! :-) This was back when the script's stdin was the script. I liked how goto worked by altering the position in the file ready for the next line, which is how we ended up with `:', familiar to users of sed(1). > I think the <<EOF ... EOF syntax was introduced by Steve Bourne > and/or John Mashey back in the before times. My understanding is Bourne introduced here files then PWB shell, Mashey's descendant, copied. Cheers, Ralph.