Search code examples
linuxbashstdoutstderr

Different ways to redirect stderr and stdout to a file in Bash?


From what I understand, 2>&1 just means 'send stderr to the same place as stdout'. But for some reason, 1>foo 2>foo and 1>foo 2>&1 don't seem equivalent.

# Assuming file 'out' exists but file 'nosuchfile' doesn't

# 'foo' contains stdout and some partial stderr in CentOS 6
$ ls -l out nosuchfile 1>foo 2>foo
$ cat foo
-rw-r--r-- 1 user user 0 May 14 14:45 out
ctory

# 'foo' contains both stdout and stderr
$ ls -l out nosuchfile 1>foo 2>&1
$ cat foo
ls: cannot access nosuchfile: No such file or directory
-rw-r--r-- 1 user user 0 May 14 14:45 out

Can anyone explain why they behave differently?


Solution

  • > overwrites files; >> appends to files.

    When you write 1> file and 2> file both streams will overwrite file in parallel and may therefore overwrite each other – a typical race condition.

    command 1>> file 2>> file should keep all output of both streams.

    Example:

    $ n=1""000""000
    $ (seq "$n" 1>&2 & seq "$n") 1> o 2> o
    $ wc -l o
    1000000
    $ rm o
    $ (seq "$n" 1>&2 & seq "$n") 1>> o 2>> o
    wc -l o
    2000000