3

I am able to redirect stdout and stderr to separate files using:

dir >> out 2>> error

or stderror and stdout together to a single file using:

dir >> consolidate 2>&1

How can I do this together (get out, error, consolidate files at a time)?

jww
  • 97,681
  • 90
  • 411
  • 885
  • 1
    Are you talking about [this](http://stackoverflow.com/a/692407/3076724)? – Reinstate Monica Please Mar 18 '14 at 04:03
  • @BroSlow I'm looking for more than that . .something like . . ls 2>>(tee error | tee -a consolidated ) && 1>>( tee out | tee -a consolidated) – user3431463 Mar 18 '14 at 04:07
  • Why can't you simply `cat out err >>consolidate` afterwards? – jfs Mar 18 '14 at 13:14
  • 2
    @J.F.Sebastian: concatenating afterwards discards the relative order of the lines. – William Pursell Mar 18 '14 at 13:38
  • 1
    ...not just "afterwards", but even recombining later in a running pipeline discards (some) ordering information. Guarantees that ordering between stdout and stderr is precisely in line with the write calls only exist when they're both served by the same file descriptor, and you can't have them served by the same file descriptor while directing their output to different places, even if they're recombined later. – Charles Duffy Mar 18 '14 at 13:47
  • 1
    @WilliamPursell: stderr is unbuffered, stdout is fully buffered then redirected. The order is already lost – jfs Mar 18 '14 at 13:49
  • @J.F.Sebastian: I agree that the ordering is not strictly maintained due to buffering, but some interleave will probably occur that may be useful, and that will definitely be lost if the files are concatenated. – William Pursell Mar 18 '14 at 14:05
  • Possible duplicate of [How to redirect stderr and stdout to different files in the same line in script?](https://stackoverflow.com/q/7901517/608639) – jww Jun 02 '19 at 01:41

2 Answers2

6

You can try something like:

(command > >(tee out.txt) 2> >(tee error.txt >&2)) &> consol.txt

Test:

$ ls
f

$ ls g*
ls: cannot access g*: No such file or directory

$ (ls g f > >(tee out.txt) 2> >(tee error.txt >&2)) &> consol.txt

$ cat out.txt
f

$ cat error.txt
ls: cannot access g: No such file or directory

$ cat consol.txt
f
ls: cannot access g: No such file or directory
jaypal singh
  • 74,723
  • 23
  • 102
  • 147
  • 1
    I wanted to suggest a simpler `{ command > >(tee out.txt) 2> >(tee err.txt); } > both.txt` but it doesn't work (`tee out.txt` receives output from `tee err.txt`) i.e., the redirection to stderr is necessary: `{ command > >(tee out.txt) 2> >(tee err.txt >&2);} &> both.txt` – jfs Mar 18 '14 at 13:17
3

There's no need for any bashisms, as this can easily be done in standard sh:

{ { dir | tee -a out; } 2>&1 >&3 | tee -a error; } >> consolidate 3>&1
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • +1 -- but with the caveat that, like every other available approach short of writing your "dir" command to log to multiple sinks itself, this doesn't guarantee correct ordering. – Charles Duffy Mar 18 '14 at 13:50