diff options
Diffstat (limited to 'public/bash-redirection.html')
-rw-r--r-- | public/bash-redirection.html | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/public/bash-redirection.html b/public/bash-redirection.html new file mode 100644 index 0000000..f846a61 --- /dev/null +++ b/public/bash-redirection.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Bash redirection — Luke T. Shumaker</title> + <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 'pipeline' is a sequence of simple commands separated by one of the +control operators '|' or '|&'. + + The format for a pipeline is + [time [-p]] [!] COMMAND1 [ [| or |&] COMMAND2 ...]</code></pre> +<p>Now, <code>|&</code> is just shorthand for +<code>2>&1 |</code>, the pipe part happens here, but the +<code>2>&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>&1 >file # stdout goes to file, stderr goes to stdout +cmd >file 2>&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 + my work 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> |