Stderr and stdout to file linux

How to redirect stderr to a file [duplicate]

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

I want to save that content to a file.

2 Answers 2

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 and zsh support it, for example, but sh and ksh 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 and strace write output to stderr by default, and may or may not provide a method of redirection specific to that command

Basic 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() and execve() syscalls, and before that happens another syscall dup2() performs necessary redirects before execve() happens. In that sense, redirections are inherited from the parent shell. The m&>n and m>n.txt inform the shell on how to perform open() and dup2() 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 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:

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

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

Читайте также:  Linux торвальдс беговая дорожка

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

Commands writing to stderr exclusively

Commands such as time and strace write their output to stderr by default. In case of time command, the only viable alternative is to redirect output of whole command , that is

alternatively, synchronous list or subshell could be redirected if you want to separate the output ( as shown in related post ):

Other commands, such as strace or dialog provide means to redirect stderr. strace has -o option which allows specifying filename where output should be written. There is also an option for writing a textfile for each subprocess that strace sees. The dialog command writes the text user interface to stdout but output to stderr, so in order to save its output to variable ( because var=$(. ) and pipelines only receives stderr ) we need to swap the file descriptors

but 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 the dialog command for thorough description of what’s happening.

Источник

How to redirect output to a file and stdout

In bash, calling foo would display any output from that command on the stdout.

Calling foo > output would redirect any output from that command to the file specified (in this case ‘output’).

Is there a way to redirect output to a file and have it display on stdout?

10 Answers 10

The command you want is named tee :

For example, if you only care about stdout:

If you want to include stderr, do:

2>&1 redirects channel 2 (stderr/standard error) into channel 1 (stdout/standard output), such that both is written as stdout. It is also directed to the given output file as of the tee command.

Furthermore, if you want to append to the log file, use tee -a as:

2>&1 dumps the stderr and stdout streams. tee outfile takes the stream it gets and writes it to the screen and to the file «outfile».

This is probably what most people are looking for. The likely situation is some program or script is working hard for a long time and producing a lot of output. The user wants to check it periodically for progress, but also wants the output written to a file.

The problem (especially when mixing stdout and stderr streams) is that there is reliance on the streams being flushed by the program. If, for example, all the writes to stdout are not flushed, but all the writes to stderr are flushed, then they’ll end up out of chronological order in the output file and on the screen.

It’s also bad if the program only outputs 1 or 2 lines every few minutes to report progress. In such a case, if the output was not flushed by the program, the user wouldn’t even see any output on the screen for hours, because none of it would get pushed through the pipe for hours.

Источник

How to redirect and append both standard output and standard error to a file with Bash

To redirect standard output to a truncated file in Bash, I know to use:

To redirect standard output in Bash, appending to a file, I know to use:

To redirect both standard output and standard error to a truncated file, I know to use:

How do I redirect both standard output and standard error appending to a file? cmd &>> file.txt did not work for me.

8 Answers 8

Bash executes the redirects from left to right as follows:

  1. >>file.txt : Open file.txt in append mode and redirect stdout there.
  2. 2>&1 : Redirect stderr to «where stdout is currently going». In this case, that is a file opened in append mode. In other words, the &1 reuses the file descriptor which stdout currently uses.

There are two ways to do this, depending on your Bash version.

The classic and portable (Bash pre-4) way is:

A nonportable way, starting with Bash 4 is

(analog to &> outfile )

For good coding style, you should

  • decide if portability is a concern (then use classic way)
  • decide if portability even to Bash pre-4 is a concern (then use classic way)
  • no matter which syntax you use, not change it within the same script (confusion!)
Читайте также:  Alt linux не обновляется

If your script already starts with #!/bin/sh (no matter if intended or not), then the Bash 4 solution, and in general any Bash-specific code, is not the way to go.

Also remember that Bash 4 &>> is just shorter syntax — it does not introduce any new functionality or anything like that.

In Bash you can also explicitly specify your redirects to different files:

Appending would be:

In Bash 4 (as well as Z shell ( zsh ) 4.3.11):

just out of box.

This should work fine:

It will store all logs in file.txt as well as dump them in the terminal.

Your usage of &> x.file does work in Bash 4. Sorry for that: (

Here comes some additional tips.

0, 1, 2, . 9 are file descriptors in bash.

0 stands for standard input, 1 stands for standard output, 2 stands for standard error. 3

9 is spare for any other temporary usage.

Any file descriptor can be redirected to other file descriptor or file by using operator > or >> (append).

Usage: >

If using older versions of Bash where &>> isn’t available, you also can do:

This spawns a subshell, so it’s less efficient than the traditional approach of cmd >> file.txt 2>&1 , and it consequently won’t work for commands that need to modify the current shell (e.g. cd , pushd ), but this approach feels more natural and understandable to me:

  1. Redirect standard error to standard output.
  2. Redirect the new standard output by appending to a file.

Also, the parentheses remove any ambiguity of order, especially if you want to pipe standard output and standard error to another command instead.

To avoid starting a subshell, you instead could use curly braces instead of parentheses to create a group command:

(Note that a semicolon (or newline) is required to terminate the group command.)

Источник

BASH Shell Redirect stderr To stdout ( redirect stderr to a File )

Table of contents

Understanding I/O streams numbers

The Unix / Linux standard I/O streams with numbers:

Tutorial requirements
Requirements Unix or Linux with bash
Root privileges No
Difficulty Easy
Est. reading time 6 mintues
Handle Name Description
0 stdin Standard input
1 stdout Standard output
2 stderr Standard error

Redirecting output

Redirecting the standard error stream to a file

The following will redirect program error message to a file called error.log:
$ program-name 2> error.log
$ command1 2> error.log
For example, use the grep command for recursive search in the $HOME directory and redirect all errors (stderr) to a file name grep-errors.txt as follows:
$ grep -R ‘MASTER’ $HOME 2> /tmp/grep-errors.txt
$ cat /tmp/grep-errors.txt
Sample outputs:

Redirecting the standard error (stderr) and stdout to file

Use the following syntax:
$ command-name &>file
We can als use the following syntax:
$ command > file-name 2>&1
We can write both stderr and stdout to two different files too. Let us try out our previous grep command example:
$ grep -R ‘MASTER’ $HOME 2> /tmp/grep-errors.txt 1> /tmp/grep-outputs.txt
$ cat /tmp/grep-outputs.txt

Redirecting stderr to stdout to a file or another command

Here is another useful example where both stderr and stdout sent to the more command instead of a file:
# find /usr/home -name .profile 2>&1 | more

Redirect stderr to stdout

Use the command as follows:
$ command-name 2>&1
$ command-name > file.txt 2>&1
## bash only ##
$ command2 &> filename
$ sudo find / -type f -iname «.env» &> /tmp/search.txt
Redirection takes from left to right. Hence, order matters. For example:
command-name 2>&1 > file.txt ## wrong ##
command-name > file.txt 2>&1 ## correct ##

How to redirect stderr to stdout in Bash script

A sample shell script used to update VM when created in the AWS/Linode server:

  • No ads and tracking
  • In-depth guides for developers and sysadmins at Opensourceflare✨
  • Join my Patreon to support independent content creators and start reading latest guides:
    • How to set up Redis sentinel cluster on Ubuntu or Debian Linux
    • How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
    • How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
    • A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
    • How to protect Linux against rogue USB devices using USBGuard

Join Patreon

Our last example uses the exec command and FDs along with trap and custom bash functions:

Want both stderr and stdout to the terminal and a log file too?

Try the tee command as follows:
command1 2>&1 | tee filename
Here is how to use it insider shell script too:

Conclusion

In this quick tutorial, you learned about three file descriptors, stdin, stdout, and stderr. We can use these Bash descriptors to redirect stdout/stderr to a file or vice versa. See bash man page here:

Operator Description Examples
command>filename Redirect stdout to file “filename.” date > output.txt
command>>filename Redirect and append stdout to file “filename.” ls -l >> dirs.txt
command 2>filename Redirect stderr to file “filename.” du -ch /snaps/ 2> space.txt
command 2>>filename Redirect and append stderr to file “filename.” awk ‘< print $4>‘ input.txt 2>> data.txt
command &>filename
command >filename 2>&1
Redirect both stdout and stderr to file “filename.” grep -R foo /etc/ &>out.txt
command &>>filename
command >>filename 2>&1
Redirect both stdout and stderr append to file “filename.” whois domain &>>log.txt

🐧 Get the latest tutorials on Linux, Open Source & DevOps via

Category List of Unix and Linux commands
Documentation help • mandb • man • pinfo
Disk space analyzers df • duf • ncdu • pydf
File Management cat • cp • less • mkdir • more • tree
Firewall Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04
Linux Desktop Apps Skype • Spotify • VLC 3
Modern utilities bat • exa
Network Utilities NetHogs • dig • host • ip • nmap
OpenVPN CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04
Package Manager apk • apt
Processes Management bg • chroot • cron • disown • fg • glances • gtop • jobs • killall • kill • pidof • pstree • pwdx • time • vtop
Searching ag • grep • whereis • which
Shell builtins compgen • echo • printf
Text processing cut • rev
User Information groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w
WireGuard VPN Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04

Comments on this entry are closed.

What this mean?
$ command > file-name 2>&1

This means redirect stdout to file-name, with that in mind redirect stderr t stdout.
This will lead to both stderr and stdout go to file-name.

Sayed: that line means execute the command while redirecting both stdout and stderr to a file given by file-name.

A slightly more correct is:
The output of the ‘command’ is redirected to a ‘file-name’ and the error chanel (that is the ‘2’ is redirected to a pointer (?) of the output (‘&1’).
So stderr goes to the stdout and that goes to the file.

Actually it means “first redirect STDERR to STDOUT, so any errors printed out on STDERR should go to STDOUT. Then, execute ‘command’ and redirect its STDOUT to ‘file-name’” – keeping in mind that at this point STDOUT will also contain whatever is written to STDERR because of the earlier redirection.

Incorrect.
There are two incorrect concepts in your answer.

First is: the redirection happens from left to right. This means that the STDOUT is redirected first.
(When you have > without a stream number, it actually have an implicit 1)
And only after STDERR is redirected to “the same place STDOUT is pointing”, meaning, ‘file-name’

Second wrong concept with your answer is: There are no connection between the descriptors. Changing STDOUT after STDERR had been redirected to STDOUT won’t change STDERR.
It will make STDERR point to STDOUT and then change STDOUT to something else (without touching STDERR)
Here is a more detailed tutorial covering both those misconceptions
http://wiki.bash-hackers.org/howto/redirection_tutorial

I like the &>file one. but not for every stiuation.

In pre-bash4 days you HAD to do it this way:

cat file > file.txt 2>&1

now with bash 4 and greater versions… you can still do it the old way …but …

cat file &> file.txt

The above is bash4+ … some OLD distros may use prebash4 but I think they are alllong gone by now. Just something to keep in mind.

I really love: “ command2>&1 | tee logfile.txt

because tee log’s everything and prints to stdout . So you stil get to see everything! You can even combine sudo to downgrade to a log user account and add date’s subject and store it in a default log directory 🙂

Hi! good explanation, I’d like to make a function on C that redirects STDIN and SDTOUT to an script, how can I do that, I mean, the exist a library’s on C to put terminal sintaxis on C?, how would you start to do it? I’m very lost with this. Thankyou!

Источник

Читайте также:  Wget proxy astra linux
Оцените статью