Before we can cover redirecting standard error we need to talk about file descriptors a file descriptor
is simply a number that represents an open file for us humans it's easier for us to reference files
by name but it's easier for computers to reference them by number by default.
Every new process starts with three open file descriptors.
They are file descriptors zero which is standard input file descriptor one which is standard output
and file descriptor 2 which is standard error.
You may be thinking hold on by default standard input comes from my keyboard but my keyboard isn't a
file and by default standard output and standard error are displayed to my screen but my screen isn't
a file either.
On one level that's true but Linux represents practically everything as a file.
Perhaps a more accurate description of a file descriptor is that it's a way that a program interacts
with files or to other resources that work like files.
These other resources include devices such as keyboards terminals and so on.
This abstraction of treating almost everything like a file allows you to do some really powerful things
like take the standard output of one command that would normally be displayed to your screen and use
it as input to another command.
Of course I'm talking about pipes in this case so file descriptors are like pointers to sources of data
or places that data can be written things like keyboards file screens and so on.
OK back to I O so far in this lesson we've been using the implicit way of redirecting input and output.
For example when we redirect standard input into a command file descriptor zero is assumed.
Let's look at the contents of a file on our system.
Now let's use that file as standard input let's say to the read command.
So we're going to read into the variable x the contents of Etsy Santos release.
Now if we echo dollar sign X we'll see the contents of that file.
So sure enough that input redirection work.
And that's the implicit way to do it.
If you want to be explicit specify the file descriptor number right before the redirection operator.
So the previous redirection is the same thing is this read x 0 less than sign Etsy Santos release and
hit enter.
And if we echo X sure enough it does the same thing.
The reason it's the same is because if you don't supply a file descriptor then zero is assumed for standard
input.
Notice that there is no space between the file descriptor zero.
In this case and the redirection operator the less than sine in this case this is very very important.
If you leave a space then what you thought was a file descriptor number that you were specifying ends
up being an argument to the command before the redirection operator so quickly.
This is wrong.
Read x 0 with a space when you intend to do redirection
and we should see an error.
And sure enough 0 is not a valid identifier that is actually coming from the read command it thinks
we specified read x 0 then let's give it some bogus data here and then hit enter.
And sure enough we get the same situation.
0 is not a valid identifier.
However this is correct read x 0 with outer space less than sine Etsy Santos release.
Now if we look at the value of x sure enough it's assigned to the contents of that file.
Let's be explicit with standard output redirection.
First let's do this.
Echo you I.D. to the file.
Let's call it you I.D. the contents of that file.
Sure enough 1000 that's her you.
No big deal.
So that was the implicit way.
If no file descriptor is given.
Then file descriptor 1 is assumed when using the greater than symbol the previous command is the exact
same thing as this.
If we specify a 1 as a file descriptor right before the greater than sign it enter and if we look at
the contents of that file it's the same thing because those two forms of redirection are the same.
Again do not use a space when supplying a file descriptor.
Let's see what happens when you do that with the Echo command here.
So we'll do your I.D. and then 1 and specify space.
Now this is the wrong way to do this.
Just want to make that clear.
Now let's use the greater than symbol to the UI file.
So now if we catch the contents of your I.D. we see we get one thousand which is what the UI variable
expands to and 1 because one was treated as an argument to echo.
So if we do this without redirection we'll see that that is what is displayed to our screen by convention
normal program output is sent to standard output while error messages are sent to standard error when
you're working at the command prompt you may not even notice the difference because again by default
they are both displayed to the screen.
Let's make a program generate an error.
First let's get some more information about the head command.
If we read the synopsis we see that file is in brackets and there's also three periods or an ellipsis
after that which means we can supply multiple files to the head command and here's what that looks like.
We'll just do head dash in one to read the first line of the Etsy password file and we'll also read
the first line of the Etsy hosts file.
So when we do this head tells us which follows displaying what lines from shows the password file the
first line from that then it shows Etsy hosts file and the first line from that.
Now let's use a file that doesn't exist.
So we'll supply something we'll name it fake file and hit enter.
So as says had cannot open forward slash fake file for reading there's no such file a directory even
though you can't tell by looking at the output there is both standard output and standard error generated
here.
Let's redirect standard output to a file run the same command the greater than sign.
We'll call this head dot out since standard error was not redirected.
It was sent to the screen and of course that error message is that file cannot be found and the normal
standard output is saved into this file red dot out.
Let's redirect standard error and the way to do that is to specify its file descriptor of 2.
So we use the same command head dash in one Etsy password.
It's a host this file that doesn't exist and then specify a file descriptor too without any spaces.
We'll use the greater than sign and then give a file to redirect this standard error to.
We'll just call this head dot e r r.
So now what comes to our screen is the standard output while the standard error goes to the file.
So let's look at the file.
Okay.
That's where the error message went.
Let's go ahead and get rid of these files for a quick head dot out and head Dot.
E r r we can even get real fancy here and redirect standard output to one file while redirecting standard
error to another.
So let's do this head dash in one Etsy password.
Etsy hosts some file that doesn't exist.
We'll redirect standard output to head out and standard error to head our art.
OK no output was displayed to the screen.
Let's look at the standard output because it's in this file and now we can look at the standard error
because it's saved in this other file.
You can probably see that this could be helpful in some situations.
If you were just concerned about errors that were being generated well you could redirect all the error
messages coming from standard error into a file for example by the way appending output is probably
what you would expect using to greater than signs assume standard out.
But even when you use a specific file descriptor such as file descriptor 2 for standard error it still
opens to the file.
So let's execute our command again here.
What we're going to change is adding the greater than symbol so we have to greater than greater than.
And then a path to a file so we'll hit enter and let's do this again will hit enter a couple other times
here and then catch the contents of head dot E R.
And sure enough we have several repetitions of the error message because we repeated that file multiple
times using append instead of overwrite what if you want to send standard output and standard error
to the same place.
There are a couple of different ways to accomplish this.
I'm going to show you the older syntax first and then the new syntax right after that.
So again we'll just use our example command here.
We're going to send the output to head up both to greater than Ampersand 1 and hit enter.
So if I can head both you're going to see the standard output and the standard error both in that one
file.
So why does that work.
Well first off you understand that greater than sine head both is a redirecting standard output to the
head that both file.
That's still the same a number that comes directly before a redirect operator is a file descriptor so
to greater than means redirect standard error.
The new piece is the ampersand symbol normally with the redirection of file follows the redirection
operator.
However if you want to use a file descriptor instead of a file name use the ampersand symbol.
So instead of redirecting standard error to a file it is being redirected to standard input.
If you were to omit the ampersand then one would be treated as a file named one.
So the command you see here on your screen head dash in one NC password and he hosts fake file greater
than header both to greater than Ampersand one sends the standard output of head to the file name head
both and append the standard error to the standard output since Standard Error is redirected to standard
output and standard output is redirected to head that both all output will be written to head both.
I'd like to point out here that spacing is important as well.
Do not use a space after the redirection operator and the ampersand.
OK let's get rid of this file head dot both.
If that seems a little confusing and hard to follow or too complicated.
No problem.
You're not alone.
Since this is a common practice new syntax was added to bash to redirect both standard input and standard
output that syntax is Ampersand greater than and then a path to a file.
So let's do our same command here had dash one couple of files that actually exist and one that doesn't.
And then we're going to use this new syntax Ampersand greater than sine and there's no spaces there
and then provide a path to a file and that path is just going to be our current directory at head dot
both.
That's much prettier and probably easier to understand in my opinion.
And if we look at head both.
Sure enough the standard output and standard error both end up there.
Again using double greater than signs appends to the file so let's prove that real quick.
We'll just do this.
Adding other greater than sign here so it's Ampersand greater than greater than that.
Enter.
And now if we cat had both we'll see two sections of output because we've ran the command twice and
the second time we appended to head.
Both
if you think back to when you first started using pipes you learned that a pipe takes the standard output
of one command and uses it as standard input for another command.
This means that standard error doesn't flow through the pipe.
Let's demonstrate this first.
Let's take a look at the cat man page
want to point out this dash in option that numbers.
All output lines so if we go back to our head command here without any redirection it looks like it
specifies six lines.
That's the password routes a blank line as he hosts one that starts with a 127 and then heads 1 2 3
4 5 6.
However if we pipe this to cat and use the dash in option Kat only counts five lines.
You see first standard error is displayed to the screen because it was not passed through the pipe.
The standard output of the head command was passed through the pipe as the input to the cat command.
The cat command numbered each file it received a standard input.
It's important to know that about pipes that you're only getting the standard output going through the
pipe.
Now this could be exactly the way you want things to work when you're working with pipes or it might
not be.
If you want to force all the output of a command through the pipe then you need to append the standard
error to the standard input.
So one way we can do this is specifying a file descriptor of 2 which is for standard error and then
redirect that into Ampersand 1 which represents file descriptor 1 which in turn represents a standard
output.
So now that standard error is going to standard output and all the standard output goes through the
pipe then cat should count all of our lines let's hit enter and see if that happens.
Sure enough it counts all six of our lines.
Now there's a shorthand for this.
It's pipe ampersand.
So instead of supplying all this food supplied pipe Ampersand it combines the standard error and standard
output into one and then passes that through the pipe.
So we get the same result.
OK.
We've covered a lot here on the command line.
Let's get back to our script and really do a mini recap of what we've been talking about and let's documented
in our script so we have something to look back to if we want to later.
So I'm going to edit our file and we're just going to be really repeating some of the examples above.
But this time using file descriptors
so we'll redirect standard into to a program using file descriptor 0
we'll just display this back
and now what we'll do is redirect standard out to a file using file descriptor one over writing that
file.
So let's do head dash in three let's see C password will be explicit here in use one and then give the
path to the file
let's just stop right here and say make changes and execute our script and see what happens so far more
or less we get a repeat of what happens at the top of the script.
We get line containing the first line of data.
Now we get the contents of temp data containing three lines as well.
Even though we use the explicit form of redirection by supplying file descriptors.
So again it works the exact same way.
Implicit or explicit.
Let's go ahead and continue editing our script here
by the way a standard error is abbreviated STV E R and standard error is a file descriptor too.
So we're going to use this error file a couple of times.
Let's create a new variable as well as a new fall for this error file r e r r file.
Let's give this temp data dot e r r
will give this file something that's going to generate an era file that doesn't exist.
We'll redirect that error message into the error file.
OK.
Let's save our changes execute our script and we get the standard output to our screen.
Let's see what the contents of this temp data e r file are.
Sure enough that's the error message that was generated by the head command that we redirected into
that file so that's doing exactly what we specified.
Let's get back into our script and keep on going here.
Now let's redirect the standard out and the standard error to a file we'll use our same head command
here.
Only this time we're going to use the new syntax the ampersand greater than sign and send that to a
file and now we'll just display the contents here.
Can't see where changes and execute our script.
And sure enough everything is displayed to our screen there.
So the standard output as well a standard error were both combined.
Now let's redirect standard output and standard error through a pipe.
We'll print a blank line and then we'll use our head command here
we'll use the new syntax if you will the latest syntax of pipe Ampersand and we'll pipe that to the
cat command with the dash in.
That's going to number the standard input that cat receives.
So we'll see where changes and execute our script.
And sure enough the error message of cannot open fake file gets passed through the pipe to cat and gets
numbered.
So we've appended standard error to standard output.
Let's do the opposite which is to append standard output to standard error.
So if we take something like the echo command and just echo the word error pipe that into cat with a
dash in option it just shows one line because one line came through a standard input into cat.
So now let's do the same thing here.
Echo Error.
But this time let's use the redirect symbol.
The ampersand which specifies a file descriptor and we'll use file descriptor too and pipe that to cat.
Now remember that the ampersand that follows the redirection operator is used when you want to use a
file descriptor instead of a file name.
And to be super clear this is exactly the same as this one greater than Ampersand 2.
Now the reason cat didn't put a line number in front of error is because the output of error never got
to cat because it was redirected to standard error so echo Error generated standard error.
So we forced echo to really generate standard error.
Now why would you ever want to do this mainly so that you can make your scripts conform to the standard
convention of sending error messages to standard error.
If you find yourself writing an exit command in a script and echoing some information just before that.
That's a really good sign that you need to send the output of those echo commands to standard error.
So let's put a demonstration of how to send output to standard error.
We'll be using this in a future script of our so we'll do echo.
This is standard error and then do this greater than Ampersand to write or changes and execute our script
now let's execute our script and redirect standard error to a file that we'll call ya.
So now if we can't e are the standard error generated by our script is in that file before we wrap up
this lesson I want to cover the null device that no device has a special file that throws away whatever
is sent to it.
Some people call this the bit bucket so if you don't want to see output on your screen and you don't
want to save that output to a file either then redirect that output to the null device which is located
at Forward slash Dev forward slash no.
So here's an example.
Had dash in one that's a password as he hosts fake file we'll just run this command and remind ourselves
what this does.
Now let's discard the standard output so we'll just send the standard output to Dev no.
So also we're left with this standard error.
Now we can do the same thing here and just throw away the standard error by doing to greater then and
then the path to the node device.
OK.
Now we don't see any error messages.
Now let's throw away all the output generated by the command and we know how to do that because we can
use this Ampersand greater than sign to combined standard output and standard error and we'll redirect
that to death.
No.
So no output is generated.
You might wonder when you would want to do such a thing well.
Here is the use case if you're executing a command in your script and you don't want the user running
the script to see that output then send it to DAB.
No.
And remember if you need to know that a command succeeded or not simply check its exit status.
You don't need the output to determine if it succeeded or failed.
So we can do this echo dollar sign question mark and we get an exit status of one which is non-zero
so something went wrong but if we make the command succeed for example take away that file that doesn't
exist and then we check the return status.
We get an exit status zero so we know that the command succeeded.
Now let's finish up our little script here by adding these examples.
Let's discard standard out
and then let's discard standard error
so we'll soon follow the too to death.
No.
And finally we'll just do an example here of discarding both a standard out and standard error
we'll put a message here to try to show that we're doing that.
And one thing I like to do is clean up after myself.
I don't like to leave temporary files just laying around so I remember that we created two files that
we were going to remove here will remove file and then we also created an error file that we can remove.
And by the way this would be a good place to send to Dev.
No.
So if for some reason the arm command fails maybe we really don't care because it's a temporary file.
We can just throw that out put away if we want to.
So let's do that.
As an example in this case.
OK.
We're almost done here we'll just exit on this file and then execute it and see what happens.
So here's the example where we discarded standard output and we're only left with the error message.
We did the reverse by discarding standard error so that only left the standard output.
And then finally we discarded both standard out and standard error.
And of course nothing was displayed to the screen in this lesson you learned a lot about input and output
redirection.
You learn that each new process starts with three open file descriptors.
They are file descriptor 0 for standard input file descriptor 1 for standard output and file descriptor
2 for standard error.
You learn that the greater than signed redirects standard output to a file and that it creates the file
if it doesn't exist or if that file does exist it truncate that file overwriting it.
You learn that you have to use double greater than signs to append to a file without overwriting it.
If no file descriptor is specified for output redirection file descriptor one is assumed that's why
you had to specify the file descriptor to to redirect standard error.
You learn that you can redirect both standard input and standard output to a file by using the ampersand
greater than sine syntax.
If you want to redirect both standard input and standard output through a pipe use the pipe Ampersand
syntax.
From there you moved on to redirecting standard input from a file into a command by using the less than
sine.
Finally you learned how to use the null device by redirecting output to Dev.
No.
I know we covered a lot in this lesson.
If this is your first time being exposed to input and output redirection I would actually encourage
you to watch this video again.
Let it soak in for now and maybe come back to it tomorrow or in a day or two.