Let's see some sample code first:
#include <stdio.h>
main()
{
// message 1, on stdout (using printf)
printf("%s", "message 1, on stdout (using printf)\n");
// message 2, on stdout (using fprintf)
fprintf(stdout, "%s", "message 2, on stdout (using fprintf)\n");
// message 3, on stderr (using fprintf)
fprintf(stderr, "%s", "message 3, on stderr (using fprintf)\n");
}
Lets compare the results:
./helloerror
+ file: no message; console: message 1,2,3;
./helloerror >error.txt
+ file: message 1,2; console: message 3;
./helloerror 2>&1 >error.txt
+ file: message 1,2; console: message 3;
+ same as ./helloerror >error.txt
./helloerror >error.txt 2>&1
+ file: message 3,1,2; console: no message;
+ note the order 3 is first, then 1, then 2
./helloerror | tee error.txt 2>&1
+ file: message 1,2; console: message 3,1,2;
+ note the order 3 is first, then 1, then 2
./helloerror 2>&1 | tee error.txt
+ file: message 3,1,2; console: message 3,1,2;
To use:
./helloerror >error.txt 2>&1
-> if one wants all(stdout+stderr) messages in file, but not pinted on console
./helloerror 2>&1 | tee error.txt
-> if one wants all(stdout+stderr) messages in file and printed on console