 <p>The subtlety you miss is that the standard input and positional parameters are not the same thing.</p> <p>Standard input, which you can redirect with the '&lt;', or even from another program with '|' is a sequence of bytes. A script can read stdin with, well, the <code>read</code> command.</p> <p>Positional parameters are numbered 1 to N and hold the value of each argument. The shell refers to them as $1 to ${42} (if you gave that many).</p> <p>Standard input and positional parameters are indepent of one another. You can have both, either, or none, depending how you call a program (and what that program expects):</p> <ol> <li>Both: <code>grep -E pattern &lt; file</code></li> <li>Just stdin: <code>wc &lt; file</code></li> <li>Just positional paramters: <code>echo Here are five positional parameters</code></li> <li>Neither: <code>ls</code></li> </ol>