This question already has an answer here:

While using nohup to put a command to run in background some of content appear in terminal.

cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error

I want to save that content to a file.

marked as duplicate by terdon Aug 27 at 14:12

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

up vote 324 down vote accepted

There are two main output streams in Linux (and other OSs), standard output (stdout) and standard error (stderr). Error messages, like the ones you show, are printed to standard error. The classic redirection operator (command > file) only redirects standard output, so standard error is still shown on the terminal. To redirect stderr as well, you have a few choices:

  1. Redirect stdout to one file and stderr to another file:

    command > out 2>error
    
  2. Redirect stderr to stdout (&1), and then redirect stdout to a file:

    command >out 2>&1
    
  3. Redirect both to a file:

    command &> out
    

For more information on the various control and redirection operators, see here.

  • 1
    So hashdeep -rXvvl -j 30 -k checksums.txt /mnt/app/ >> result_hashdeep.txt 2> error_hashdeep.txt & or hashdeep -rXvvl -j 30 -k checksums.txt /mnt/app/ >> result_hashdeep.txt 2>&1 or hashdeep -rXvvl -j 30 -k checksums.txt /mnt/app/ &> result_mixed.txt – André M. Faria May 18 '15 at 12:59
  • 3
    @AndréM.Faria yes. But the last two commands are equivalent, they will send both error and output to the same file. – terdon May 18 '15 at 13:17
  • 2
    As in the link you provided, I could use |& instead of 2>&1 they are equivalent, thanks for you time. – André M. Faria May 18 '15 at 13:38
  • 3
    Hi, I was able to simplify this to: command 2> out. – Surya Teja Karra Dec 11 '16 at 8:00
  • 6
    @SuryaTejaKarra that only redirects stderr, but not stdout. – terdon Dec 11 '16 at 11:35

First thing to note is that there's couple of ways depending on your purpose and shell, therefore this requires slight understanding of multiple aspects. Most typical, is via 2> in Bourne-like shells, such as dash (which is symlinked to /bin/sh) and bash; first is the default and POSIX-compliant shell and the other is what most users use for interactive session. They differ in syntax and features, but luckily for us error stream redirection works the same (except the &> non standard one). In case of csh and its derivatives, the stderr redirection doesn't quite work there.

Let's come back to 2> part. Two key things to notice: > means redirection operator, where we open a file and 2 integer stands for stderr file descriptor; in fact this is exactly how POSIX standard for shell language defines redirection in section 2.7:

[n]redir-op word

For simple > redirection, the 1 integer is implied for stdout, i.e. echo Hello World > /dev/null is just the same as echo Hello World 1>/dev/null. Note, that the integer or redirection operator cannot be quoted, otherwise shell doesn't recognize them as such, and instead treats as literal string of text. As for spacing, it's important that integer is right next to redirection operator, but file can either be next to redirection operator or not, i.e. command 2>/dev/null and command 2> /dev/null will work just fine.

The somewhat simplified syntax for typical command in shell would be

 command [arg1] [arg2]  2> /dev/null

The trick here is that redirection can appear anywhere. That is both 2> command [arg1] and command 2> [arg1] are valid. Note that for bash shell, there there exists &> way to redirect both stdout and stderr streams at the same time, but again - it's bash specific and if you're striving for portability of scripts, it may not work. See also Ubuntu Wiki and What is the difference between &> and 2>&1.

Note: The > redirection operator truncates a file and overwrites it, if the file exists. The 2>> may be used for appending stderr to file.

If you may notice, > is meant for one single command. For scripts, we can redirect stderr stream of the whole script from outside as in myscript.sh 2> /dev/null or we can make use of exec built-in. The exec built-in has the power to rewire the stream for the whole shell session, so to speak, whether interactively or via script. Something like

#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file

In this example, the log file should show stat: cannot stat '/etc/non_existing_file': No such file or directory.

Yet another way is via functions. As kopciuszek noted in his answer, we can write function declaration with already attached redirection, that is

some_function(){
    command1
    command2
} 2> my_log_file.txt

Not the answer you're looking for? Browse other questions tagged or ask your own question.