8
program 2> error.log 
program &> filename 
program >> filename 2>&1
program 2>&1

I was able to figure out what these lines mean.

However I don't quite understand where I should put the spaces. I also worry that it actually doesn't matter where to put spaces. Thanks for reading.

4
  • 3
    what are you asking here actually? Could you formulate... you know, a question? ;)
    – Zanna
    Dec 5, 2017 at 9:21
  • What does the second line do? I haven't seen this syntax before. Dec 5, 2017 at 9:47
  • 3
    @StefanHamcke, See also this link, askubuntu.com/questions/958967/… ; The token &> can be used to redirect both the standard error and standard output. It can be used in bash, but may not be available in other shells.
    – sudodus
    Dec 5, 2017 at 9:54
  • Sorry, my original question was not clear as a question. Fortunately askubuntu.com changed it with right grammar and phrase. I'll try to be better next time.
    – Smile
    Dec 5, 2017 at 11:16

2 Answers 2

13

Yes, spacing between words and redirections doesn't matter. That's the short answer.

The details lie in the fact that shell ( for simplicity let's just refer to bash only) treates certain characters and groups of characters as "words" and "metacharacters". From bash 4.3 manual:

metacharacter

A character that, when unquoted, separates words. One of the following:

|  & ; ( ) < > space tab

And

word A sequence of characters considered as a single unit by the shell. Also known as a token.

So when we do:

$ echo "hello world">/dev/null

or

$ echo "hello world" > /dev/null

that's still 3 words ("hello world" can be considered a single shell word because it's quoted), with one > meta character and couple spaces. Shell will see it, and perform redirection first (so it looks for meta characters first), and then runs commands in accordance with its standard behavior.

Order of redirections, however, matters a lot, especially when you're duplicating file descriptors with something like 2>&1. Say you want to get send both stderr and stdin to same location. Here's a wrong way to do it:

$ stat ./non-existent file 2>&1  > /dev/null
stat: cannot stat './non-existent': No such file or directory
stat: cannot stat 'file': No such file or directory

You're making file descriptor 2 output to same location as 1, which is your terminal, but it was already doing so. That's why stderr shows up.

If you redirect stdout first, and only then change where 2 points - then it'll work:

$ stat ./non-existent file > /dev/null 2>&1 
6
  • Thanks for the detailed and practical answer. I feel like I'll never be proficient with redirection. When can I achieve your level, Zanna??
    – Smile
    Dec 5, 2017 at 11:28
  • 4
    Will "echo foo2>bar" be interpreted as "echo foo 2>bar" or "echo foo2 >bar" Dec 5, 2017 at 14:51
  • @Smile I only made a tiny edit to the grammar of this question. Sergiy is the author and the knowledgeable one!
    – Zanna
    Dec 5, 2017 at 15:08
  • 1
    @PeterGreen It will be echo foo2 > bar.
    – wjandrea
    Dec 5, 2017 at 16:54
  • 2
    @PeterGreen good question ! It will be interpreted as echo foo2 >bar because if we split the command into separate tokens using space and > as metacharacters, it will be 3 words: echo, foo2, and bar. Only when filedescriptor number appears by itself on the line, then it's considered as separate item, otherwise it's part of another word. Dec 5, 2017 at 17:42
1

Spacing doesn't matter except a few special cases.

  1. You have a digit before the standard output redirection.
    According to the Bash manual:

if the file descriptor number is omitted, and the first character of the redirection operator is ‘<’, the redirection refers to the standard input (file descriptor 0). If the first character of the redirection operator is ‘>’, the redirection refers to the standard output (file descriptor 1).

So, for example, echo test 2 > output.txt will be interpreted as echo test 2 1> output.txt, i.e. redirect the stdout of the command echo test 2 to the file output.txt which will create the file containing the text "test 2".
On the other hand, echo test 2> output.txt will be interpreted as "redirect the stderr (file descriptor 2) of the command echo test to the file output.txt", which will be empty because the stderr of the command is empty.
This behavior is not limited to digits 1 and 2. So echo test 5> output.txt will also create an empty file.

  1. When using process substitution in the form <(...) or >(...), space between the left parentheses and the > or < is not allowed.

Note that no space may appear between the < or > and the left parenthesis, otherwise the construct would be interpreted as a redirection.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .