Fighting useless use of cat

Fighting UUOC

cat filename|while read line; do ...

with

sed 's/cat *\([^ ][^ ]*\) *|/<\1/g'

I found that while loops are converted to

<filename while read line; do ...

Syntax error!
Why syntax error? It would perfectly make sense.
Further, read the article how-would-you-like-your-loops-served-today
Then I tested with the best shell ever, zsh.
It works!

It's done like this:

while read lone
do
...
done < inputfile

Blindly editing code with sed is an even more dangerous idea than UUOC.

Both should work!
I can do an instantly readable

<filename awk '
# mega
# tons
# of
# code
'

Much better than

awk '
# mega
# tons
# of
# code
' <filename

Logically, the same should apply to a while loop.

Hi.

The documentation says:

REDIRECTION
       Before a command is executed, its input and output may be redirected
       using a special notation interpreted by the shell.  Redirection may
       also be used to open and close files for the current shell execution
       environment.  The following redirection operators may precede or appear
       anywhere within a simple command or may follow a command.  Redirections
       are processed in the order they appear, from left to right.

-- excerpt from man bash

Because the statement in question is not a simple command, then syntax, design, and code prevail over what may seem logical.

I note that ksh and dash also fail to process as you desire, but, I agree, zsh seems OK with the short tests I did.

Best wishes ... cheers, drl

( Edit 1: grammar correction )

while is not an external command, it's a shell builtin. The same rules don't always apply. That you can redirect into them at all is a huge blessing and feature rather unique to Bourne-based shells.

Hi.

Minor quibble, not a builtin, but a reserved word:

RESERVED WORDS
       Reserved words are words that have a special meaning to the shell.  The
       following words are recognized as reserved when unquoted and either the
       first word of a simple command (see SHELL GRAMMAR below) or the third
       word of a case or for command:

       ! case  do done elif else esac fi for function if in select then until
       while { } time [[ ]]

But I take your point.

Best wishes ... cheers, drl

2 Likes