summaryrefslogtreecommitdiff
path: root/public/bash-redirection.html
diff options
context:
space:
mode:
Diffstat (limited to 'public/bash-redirection.html')
-rw-r--r--public/bash-redirection.html61
1 files changed, 61 insertions, 0 deletions
diff --git a/public/bash-redirection.html b/public/bash-redirection.html
new file mode 100644
index 0000000..f69a881
--- /dev/null
+++ b/public/bash-redirection.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Bash redirection — Luke T. Shumaker</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" href="assets/style.css">
+ <link rel="alternate" type="application/atom+xml" href="./index.atom" name="web log entries"/>
+</head>
+<body>
+<header><a href="/">Luke T. Shumaker</a> » <a href=/blog>blog</a> » bash-redirection</header>
+<article>
+<h1 id="bash-redirection">Bash redirection</h1>
+<p>Apparently, too many people don’t understand Bash redirection. They
+might get the basic syntax, but they think of the process as
+declarative; in Bourne-ish shells, it is procedural.</p>
+<p>In Bash, streams are handled in terms of “file descriptors” of “FDs”.
+FD 0 is stdin, FD 1 is stdout, and FD 2 is stderr. The equivalence (or
+lack thereof) between using a numeric file descriptor, and using the
+associated file in <code>/dev/*</code> and <code>/proc/*</code> is
+interesting, but beyond the scope of this article.</p>
+<h2 id="step-1-pipes">Step 1: Pipes</h2>
+<p>To quote the Bash manual:</p>
+<pre><code>A &#39;pipeline&#39; is a sequence of simple commands separated by one of the
+control operators &#39;|&#39; or &#39;|&amp;&#39;.
+
+ The format for a pipeline is
+ [time [-p]] [!] COMMAND1 [ [| or |&amp;] COMMAND2 ...]</code></pre>
+<p>Now, <code>|&amp;</code> is just shorthand for
+<code>2&gt;&amp;1 |</code>, the pipe part happens here, but the
+<code>2&gt;&amp;1</code> part doesn’t happen until step 2.</p>
+<p>First, if the command is part of a pipeline, the pipes are set up.
+For every instance of the <code>|</code> metacharacter, Bash creates a
+pipe (<code>pipe(3)</code>), and duplicates (<code>dup2(3)</code>) the
+write end of the pipe to FD 1 of the process on the left side of the
+<code>|</code>, and duplicate the read end of the pipe to FD 0 of the
+process on the right side.</p>
+<h2 id="step-2-redirections">Step 2: Redirections</h2>
+<p><em>After</em> the initial FD 0 and FD 1 fiddling by pipes is done,
+Bash looks at the redirections. <strong>This means that redirections can
+override pipes.</strong></p>
+<p>Redirections are read left-to-right, and are executed as they are
+read, using <code>dup2(right-side, left-side)</code>. This is where most
+of the confusion comes from, people think of them as declarative, which
+leads to them doing the first of these, when they mean to do the
+second:</p>
+<pre><code>cmd 2&gt;&amp;1 &gt;file # stdout goes to file, stderr goes to stdout
+cmd &gt;file 2&gt;&amp;1 # both stdout and stderr go to file</code></pre>
+
+</article>
+<footer>
+ <aside class="sponsor"><p>I'd love it if you <a class="em"
+ href="/sponsor/">sponsored me</a>. It will allow me to continue
+ <a class="em" href="/imworkingon/">my work</a> on the GNU/Linux
+ ecosystem. Thanks!</p></aside>
+
+<p>The content of this page is Copyright © 2014 <a href="mailto:lukeshu@lukeshu.com">Luke T. Shumaker</a>.</p>
+<p>This page is licensed under the <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a> license.</p>
+</footer>
+</body>
+</html>