summaryrefslogtreecommitdiff
path: root/public
diff options
context:
space:
mode:
authorLuke Shumaker <LukeShu@sbcglobal.net>2014-05-08 14:36:47 -0400
committerLuke Shumaker <LukeShu@sbcglobal.net>2014-05-08 14:36:47 -0400
commitc154a2096801851c1ec9588d30899603d605b519 (patch)
treed1d347ddeecc39459f8a4d26ba0e6bad2c8abe57 /public
parent604a665b0ed06801e77aaf7fbc194c33abff9679 (diff)
Hmm, this was sitting on my laptop
Diffstat (limited to 'public')
-rw-r--r--public/bash-redirection.md50
1 files changed, 50 insertions, 0 deletions
diff --git a/public/bash-redirection.md b/public/bash-redirection.md
new file mode 100644
index 0000000..8da02b3
--- /dev/null
+++ b/public/bash-redirection.md
@@ -0,0 +1,50 @@
+Bash redirection
+================
+---
+date: "2014-02-13"
+---
+
+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.
+
+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 `/dev/*` and `/proc/*` is interesting, but
+beyond the scope of this article.
+
+Step 1: Pipes
+-------------
+
+To quote the Bash manual:
+
+ 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 ...]
+
+Now, `|&` is just shorthand for `2>&1 |`, the pipe part happens here,
+but the `2>&1` part doesn't happen until step 2.
+
+First, if the command is part of a pipeline, the pipes are set up.
+For every instance of the `|` metacharacter, Bash creates a pipe
+(`pipe(3)`), and duplicates (`dup2(3)`) the write end of the pipe to
+FD 1 of the process on the left side of the `|`, and duplicate the
+read end of the pipe to FD 0 of the process on the right side.
+
+Step 2: Redirections
+--------------------
+
+*After* the initial FD 0 and FD 1 fiddling by pipes is done, Bash
+looks at the redirections. **This means that redirections can
+override pipes.**
+
+Redirections are read left-to-right, and are executed as they are
+read, using `dup2(right-side, left-side)`. 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:
+
+ cmd 2>&1 >file # stdout goes to file, stderr goes to stdout
+ cmd >file 2>&1 # both stdout and stderr go to file