How do programs output to elsewhere than STDOUT/STDERR? How to avoid it?
The syntax you used is wrong.
cmd &2>1 >file
will be split down as
cmd &
2>1 >file
This will:
- Run
cmd
as a background job with no redirections - In a separate process (without a command!) will redirect
stderr
to a file literally called1
and redirectstdout
tofile
The syntax you want is:
cmd >file 2>&1
The order of operations is important. This will:
- Redirect
stdout
tofile
- Redirect
stderr
to&1
- ie the same filehandle asstdout
The result is that both stderr
and stdout
will be redirected to file
.
In bash
, a simpler non-standard (and so I don't recommend it, on portability grounds) syntax of cmd &> file
does the same thing.
There are two problems.
The first one is that the order matters, the second one is /dev/tty
.
Let's use this script as an example script that we want to capture output from:
test.sh
:
#!/bin/bash
echo dada
echo edada 1>&2
echo ttdada >/dev/tty
Now let's see the outputs of the commands:
./testmyscript.sh 2>&1 >/dev/null
:
edada
ttdada
Because the order of evaluation is from left to right, we first get "redirect stderr
to wherever stdout
is outputting(so, console output)". Then we get "redirect stdout
to /dev/null
. We end up with situation like this:
stdout
-> /dev/null
stderr
-> console
So we get it right:
./testmyscript.sh >/dev/null 2>&1
And we get:
ttdada
.
Now we do "Redirect stdout
to /dev/null
", and then "Redirect stderr to where stdout is pointing"(so, /dev/null
). Hurray!
However, we still have a problem; program prints to /dev/tty
. Now I don't know how to fix this kind of behaviour, so you're most likely going to need script
, but hopefully this behaviour won't happen too often.