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.
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:Redirect stdout to one file and stderr to another file:
Redirect stdout to a file (
>out
), and then redirect stderr to stdout (2>&1
):Redirect both to a file (this isn't supported by all shells,
bash
andzsh
support it, for example, butsh
andksh
do not):For more information on the various control and redirection operators, see here.
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. Additionally, certain commands such as
time
andstrace
write output to stderr by default, and may or may not provide a method of redirection specific to that commandBasic theory behind redirection is that a process spawned by shell (assuming it is an external command and not shell built-in) is created via
fork()
andexecve()
syscalls, and before that happens another syscalldup2()
performs necessary redirects beforeexecve()
happens. In that sense, redirections are inherited from the parent shell. Them&>n
andm>n.txt
inform the shell on how to performopen()
anddup2()
syscall (see also How input redirection works, What is the difference between redirection and pipe, and What does & exactly mean in output redirection )Shell redirections
Most typical, is via
2>
in Bourne-like shells, such asdash
(which is symlinked to/bin/sh
) andbash
; 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 and2
integer stands for stderr file descriptor; in fact this is exactly how POSIX standard for shell language defines redirection in section 2.7:For simple
>
redirection, the1
integer is implied forstdout
, i.e.echo Hello World > /dev/null
is just the same asecho 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
andcommand 2> /dev/null
will work just fine.The somewhat simplified syntax for typical command in shell would be
The trick here is that redirection can appear anywhere. That is both
2> command [arg1]
andcommand 2> [arg1]
are valid. Note that forbash
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. The2>>
may be used for appendingstderr
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 inmyscript.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 likeIn 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
Commands writing to stderr exclusively
Commands such as
time
andstrace
write their output to stderr by default. In case oftime
command, the only viable alternative is to redirect output of whole command , that isalternatively, synchronous list or subshell could be redirected if you want to separate the output ( as shown in related post ):
Other commands, such as
strace
ordialog
provide means to redirect stderr.strace
has-o <filename.txt>
option which allows specifying filename where output should be written. There is also an option for writing a textfile for each subprocess thatstrace
sees. Thedialog
command writes the text user interface to stdout but output to stderr, so in order to save its output to variable ( becausevar=$(...)
and pipelines only receives stderr ) we need to swap the file descriptorsbut additionally, there is
--output-fd
flag, which we also can utilize. There's also the method of named pipes. I recommend reading the linked post about thedialog
command for thorough description of what's happening.