One thing worth noting is that "redirection of streams" is a poor metaphor.<p>If I have two streams,<p><pre><code> 1 ---------- 1'
2 ---------- 2'
</code></pre>
and I redirect the 1>2<p><pre><code> 1 ----
\
2 ---------- 2'
</code></pre>
it seems to work okay.<p>But if you have three,<p><pre><code> 1 ---------- 1'
2 ---------- 2'
3 ---------- 3'
</code></pre>
and try "redirecting 1 to 2 then 2 to 3", the natural reading would be<p><pre><code> 1 -
\
2 -----
\
3 ---------- 3'
</code></pre>
But that's not what you get, because you're not "redirecting streams" - you're copying file descriptors. This is partially fixed by informing people to do the operations backwards, but there are corner cases where that breaks down, and "copying file descriptors in the order they appear on the line" never does because that's genuinely what's going on.<p><pre><code> 1 -> 1'
2 -> 2'
3 -> 3'
</code></pre>
foo 1>2 2>3<p>This is "run foo copying fd 2 to 1 and 3 to 2"<p>which gives<p><pre><code> 1 -> 2'
2 -> 3'
3 -> 3'</code></pre>
I think I previously had all the pieces required to do this, but only just figured out that it worked:<p><pre><code> Glenn-Willens-MacBook-Pro:~ gwillen$ exec 3<> /dev/tcp/<website>/80
Glenn-Willens-MacBook-Pro:~ gwillen$ echo "GET / HTTP/1.0" >&3
Glenn-Willens-MacBook-Pro:~ gwillen$ echo "" >&3
Glenn-Willens-MacBook-Pro:~ gwillen$ cat <& 3
HTTP/1.1 200 OK
Date: Mon, 10 Sep 2012 21:43:33 GMT
Server: Apache
Last-Modified: Sun, 06 Sep 2009 18:44:42 GMT
ETag: "30525-0-472ed20537a80"
Accept-Ranges: bytes
Content-Length: 0
Connection: close
Content-Type: text/html
Glenn-Willens-MacBook-Pro:~ gwillen$</code></pre>
One thing missing is <<- heredocs, which strip (some) leading whitespace. It lets you keep up your indentation in a shell script without passing a bunch of whitespace to the commands.
I've found<p><pre><code> cmd <(another_cmd)
</code></pre>
to be particularly useful in the past for pushing generated data into something that doesn't accept - as an alias for STDIN. I'm not sure if it's a different way of expressing one of the listed items though; iirc it creates a temporary fifo
I've always done<p><pre><code> (cmd 2>&1) > file
</code></pre>
to redirect stderr and stdout to a file. I always thought the parenthesis were necessary, but according to this I can just do<p><pre><code> cmd > file 2>&1
</code></pre>
It seems very unintuitive, though. Does anyone know the rationale behind ordering of redirects?<p>(That said, I'm going to use 'cmd &> file' that I just learned from now on)
The network pseudo filehandles (/dev/tcp/<host>/<port> and /dev/udp/<host>/<port>) are explicitly disabled in certain distros (notably Debian). Ubuntu appears to support it.<p>Though not limited to just shell redirections, one of the true masters of bash (and zsh) is Larry Peek whose written/given multiple books, articles, and presentations on the topic.
I can never remember the (ba)sh redirection syntax, and I used it for decades.<p>Rc on the other hand is much more clean: <a href="http://rc.cat-v.org" rel="nofollow">http://rc.cat-v.org</a>
the "cmd <<EOL ..\n..\n EOL" part has been mystical to me for ages, especially as I didn't know what to google to find out. I recently learned it was called a "Here Document". <a href="http://en.wikipedia.org/wiki/Here_document" rel="nofollow">http://en.wikipedia.org/wiki/Here_document</a><p>For extra credit, try using a "Here Document" as input for 'echo' and 'cat'. Explain the results.