From 75081c63ee8b204a239572a232d50455556882f4 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 21 Mar 2016 01:55:24 -0400 Subject: Go ahead and add the generated files. So I know about regressions. --- public/bash-redirection.html | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 public/bash-redirection.html (limited to 'public/bash-redirection.html') diff --git a/public/bash-redirection.html b/public/bash-redirection.html new file mode 100644 index 0000000..1cb3b3b --- /dev/null +++ b/public/bash-redirection.html @@ -0,0 +1,35 @@ + + + + + Bash redirection — Luke Shumaker + + + +
Luke Shumaker » blog » bash-redirection
+
+

Bash redirection

+

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
+ +
+ + + -- cgit v1.2.3-2-g168b