What is STDOUT and STDERR in Linux - echo to STDERR

Every command we run in Linux would either give output or throw an error. Sometimes we want the errors to be redirected into an output channel or you may want to redirect the STDERR to one file and STDOUT to a different file

You might have come across these two words often STDOUT and STDERR and wondered what is this.

So in this post, we are going to see what is STDOUT and STDERR in Linux and how to use them and how to echo to STDERR and how to use the output redirections like >&2 and 2>&1 to redirect the STDOUT and STDERR into the other channel.

Bash echo to STDERR

So What is STDERR and STDOUT in Linux?

You might have heard or read that Linux handles everything as a file and In Linux, everything is a file.

Well. That's true.

In fact, Even the input and output of any process running on the Linux system is also considered as a file.

Linux identifies each file objects with file descriptor  A non-negative integer that represents the open files in the session. the bash shell reserves the first three file descriptors 0, 1, 2

File Descriptor  Abbreviation Description
0 STDIN Standard Input
1 STDOUT Standard Output
2 STDERR Standard Error

These three special file descriptors handle the input and output from your script or a process.

while STDIN or Standard Input helps the Linux Process or a script to get its input from the user ( typing in the keyboard) the Standard output STDOUT and Error STDERR helps to display the result to the user on the monitor.

Linux has given us two file descriptors or channels to distinguish the Output and the Error so that we can redirect them to two different locations or files as per our requirement.

Now having this basic understanding. let us go and see how to use this STDOUT and STDERR with Linux commands.

 

Default Behaviour of any command in Linux

By Default, Any Linux command that you take would display its error (or) output to the  STDOUT only

For example, consider the following commands

# List two files - one is present and another one is not
bash-3.2$ ls -lrt test test.sh
ls: test: No such file or directory
rwxr-xr-x  1 sarav  wheel  95 Jan 25 04:18 test.sh

If you look at the preceding command you can see that we are trying to list two files at the same time. Amongst them, one is not present.

Technically the command we have executed has something to send to STDERR and STDOUT  but both error and output are displayed in the same standard output channel (monitor/terminal)

But why?

As said earlier, By Default both stdout and stderr would be displayed in the stdout channel only.

Modify the command to redirect the error STDERR to a file

Let us use the same command and try to redirect the error to a file and display only the output to the standard output channel (monitor/terminal)

bash-3.2$ ls -lrt test test.sh 2>/tmp/errorlog
-rwxr-xr-x  1 sarav  wheel  95 Jan 25 04:18 test.sh

Now you can see only the valid output is printed while the error message is not and been redirected to a file named /tmp/errorlog If you open and see the file you would see the error message we have noticed previously.

Here is the snapshot of my execution.


In the preceding snapshot, you could see that the first command has redirected the error to the file named /tmp/errorlog and the second command displays the content of the file to make sure that the error is present.

So how we did it.

Using the redirection symbol > and with the file descriptor numeric value of STDERR 2

by 2> we are instructing the shell to redirect the errors to a file.

How to Redirect the Output and Error to different files.

In the previous command, we just redirected the stderr into the file and displayed the standard output on the terminal.

But If we want to redirect the stdout and stderr to two different files at the same time.

here is the updated command.

bash-3.2$ ls -lrt test test.sh 1> /tmp/outputlog 2>/tmp/errorlog

In the preceding command, you can notice we are using the same strategy of prefixing the file descriptor numeric value of stdout and stderr with the redirection symbols followed by the appropriate file names.

1> /tmp/outputlog redirects the stdout to the outputlog file

2>/tmp/errorlog redirects the stderr to the errorlog file.

Hope it helped you to understand the stdout and stderr and how to use them

Bash echo to STDERR - echo to the standard error or stderr

We all know that the bash echo command prints everything that you give after that. In fact, echo command does not even return any error or nonzero return code.

Then how to make echo command to echo something to the stderr

Consider the following script with two echo messages. The First echo command contains a string which supposed to go the STDERR

 #!/bin/bash
 # testing STDOUT & STDERR
 echo "This is an error"
 echo "This is normal output"

but when you run this script you would get both these messages on the standard output or stdout

So how to make echo command to echo something to the stderr instead of stdout.

We are going to apply the same trick of  file descriptors and redirection symbol

Here is the modified script

 #!/bin/bash
 # testing STDOUT & STDERR
 echo "This is an error" >&2
 echo "This is normal output"

All we had to add is >&2

What we are doing here is redirecting the stdout into the stderr channel

 

How to redirect STDERR to STDOUT in Linux

In most cases,  we would be redirecting the error stream to output stream so that we do not miss anything or to stop it from being printed on the terminal.In other words,

The best example is while scheduling a cron job. When you want to run some script using CRON. It is necessary that we capture all the possible outputs or errors that the script would throw as it runs. which would be used for troubleshooting or auditing later.

So we must redirect the error and output both into the same stream. Mostly we redirect the error(STDERR) into the output stream(STDOUT) and save both of them into a single file.

The command to do that is 2>&1

So what is this 2>&1

Here 2 is the file descriptor of standard error and we are redirecting the stderr(error) into the stdout (normal output) channel, which has the filedescriptor value as 1.  You can consider the & ampersand as along with

This is how you should use this command. Especially while scheduling a job/script in crontab.

 ./somescript.sh > /tmp/output.log 2>&1

here the error and output both would be saved into the same file named output.log

 

A Best Practice to echo the stdout and stderr into two different files in Shell script - LOGGING

Let's say you are creating a script and you want to capture the errors and outputs into two different log files.

Instead of adding >&2 all the way for each echo command. You can rather write a quick function like this.

Refer the following script.

#!/bin/bash

function errlog()
{
   echo $1 >>/tmp/errorlog
}

function outlog
{
   echo $1 >>/tmp/outputlog
}


echo  "Enter the username to Signin"
read name

if [ $name != "Sarav" ]
then
     errlog "Some Invalid user tried to login with the username $name at `date`"
     echo "You are not a valid user!. This incident is reported"
else
     echo "Welcome Sarav!"
     outlog "Sarav has logged in at `date`"
fi

The preceding sample script is to validate the user in a very simple way by getting their name.  It is designed to welcome only if the username is Sarav

Otherwise, It would print some error message to the user and also log some audit info to the error log file.

we have declared two functions here named as errlog and outlog which is being used as a logger to log the messages to the write files.

I have been using such methods for a very long time in my experience and I hope you like it and find it useful.

here is the execution of this script.

Note*: I have updated the script. and replaced the > single redirection to >> double redirection symbol as the single one would rewrite the file and double redirection would append the file. So for logging purpose you need >> this

 

Conclusion

In this article, we have seen how to echo to stderr and redirect the stderr to stdin and vice versa. Hope you have also learnt the basics about linux file descriptors.

Hope it helps.

 

For Further reads

I have listed down some of my favourite books and you click on them to buy it

1# Linux Command Line and Shell scripting

2# Mastering Linux Shell scripting

 

Cheers
Sarav AK

Follow me on Linkedin My Profile
Follow DevopsJunction onFacebook orTwitter
For more practical videos and tutorials. Subscribe to our channel

Buy Me a Coffee at ko-fi.com

Signup for Exclusive "Subscriber-only" Content

Loading