What does ">> file command" do, and how does it differ from "command >> file"?

Picking up from this highly voted comment to What does `>>` mean in terminal command?:

"program before" What does that mean? Command obviously, but redirections can also be written prepended, i.e. >> file command

I don't remember having seen such a case - although, given the amount of upvotes, they clearly exist. I have only ever seen and used redirection commands of the format

command >> file

when using >> and its ilk (i.e. 2>, 2>&1, etc.).

When and why would you reverse the order? Does it mean that all stdout is redirected, not only that from command? Does anyone have any concrete examples?

I have had a google and could find any immediate examples.


Solution 1:

>> file command
Does it mean that all stdout is redirected, not only that from command?

Such redirection affects a simple command. From man 1 bash:

Before a command is executed, its input and output may be redirected using a special notation interpreted by the shell. […] The following redirection operators may precede or appear anywhere within a simple command or may follow a command. Redirections are processed in the order they appear, from left to right.

"The following redirection operators" are [n]<word, [n]>word, [n]>>word etc.

A simple command is a sequence of optional variable assignments followed by blank-separated words and redirections, and terminated by a control operator.

And

control operator
A token that performs a control function. It is one of the following symbols:
|| & && ; ;; ( ) | |& <newline>

This means the following commands are equivalent:

echo Some text >> file
echo Some >> file text
echo >> file Some text
>> file echo Some text

The question is tagged bash and I quote man 1 bash but the above commands work in sh as well.

The command line parser needs to "serve" all redirections before it runs the command (i.e. the command stripped of these redirections). Think about it, the procedure is the same regardless of where the particular redirection is. There's no reason to require it to be at the very end.


When and why would you reverse the order?

I don't recall a situation where I wanted to have a redirection in the middle. There is, however, a usage case where having an input redirection at the beginning is quite useful. Consider this code:

grep foo file | tail | …

Imagine the pipe is very long. It's posted on Super User and solves some problem. You may paste it to your console and run it. What if you'd rather want to append it to some command or pipe? E.g. you want to get:

my_custom_command | grep foo | tail | …
#                   ^^^^^^^^^^^^^^^^^^^ this is the part you'd be happy to paste

You need to remove file from the copied command. For this reason some users prefer posting commands like this:

cat file | grep foo | tail | …
#          ^^^^^^^^^^^^^^^^^^^ it's easy to copy this
#        ^^^^^^^^^^^^^^^^^^^^^ or even this

In other circumstances this would be totally useless use of cat. Some would say it still is, regardless of the circumstances. How about:

< file grep foo | tail | …
#      ^^^^^^^^^^^^^^^^^^^ it's easy to copy this

No cat and a convenient form!

Solution 2:

Explanation

The key to understanding how I/O redirection operators work is remembering that you're working within a shell that is constantly printing to STDOUT, or STDERR(mainly) with every command you enter.

>> doesn't care how the output happens, but only that when it does happen it can append it to the file that directly follows it. It's also important to keep in mind that redirection operators aren't going to get involved in your commands. You can test things further by typing echo hello >> newfile this is my output and when you cat newfile you'll see: "hello this is my output".

In this particular case, the order of the commands in combination with the append operator(>>) isn't necessarily the important thing to watch. Instead, watch the result of your commands, as eluded to by Kamil's comment above^. As long as something that's not an error prints in your shell, >> can do its thing.

The echo command's job is to print to standard output(STDOUT). Try it on its own and you'll see a new line with your output. If you include >> file in the mix, you'll have whatever appears on that newline appended into that file. The order of this is important, however. The file to append to must directly succeed the operator.

Note on Examples

Regarding concrete examples, I would say you won't find many of those since switching up the order is seen as less intuitive/readable than a couple of arrows that point from one source to another. Further, when you're writing verbose shell scripts, there is even greater a need for intuitive and readable code.


If you wish to have an even deeper understanding of this, you can start learning about file descriptors(STDIN, STDOUT, STDERR) and how Unix system calls works. This all can be seen as a window into Unix System Programming and how Unix/Linux works on a deeper level.