What does ">> file command" do, and how does it differ from "command >> file"?
>> file command
Does it mean that allstdout
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!
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.