I often see other people’s shell scripts followed by a
2>&1, and have never bothered to look deeper, so today this topic will be the starting point to expand and learn about the topic of redirection in the linux shell.
First, let’s look at some special things in linux to lay the groundwork for the rest of the content.
/dev/nullempty, you can import garbage content into it and it will disappear
/dev/zerozero, you can read endless zeros from it
/dev/urandomrandom numbers, you can read endless random numbers from it
/dev/stdinstandard input stream
/dev/stdoutStandard output stream
/dev/stderrstandard error output stream
We can see that the last three files are actually links to the kernel’s file descriptors 0\1\2.
Special file descriptors
There are three special file descriptors (
File descriptor or
fd) in the Linux shell:
0is the standard input:
1is the standard output:
2is the standard error output:
With these three special file descriptors we can control the input and output streams.
We often come across the symbol
>, called a redirect, but there is another symbol
>> that has a similar function, with a small difference between them.
>>is an overwrite method.
>>is an append method.
The following contents will all be
>as an example,
>>has no other difference except that the content is appended, so I won’t repeat it.
Redirecting to a file
Let’s first look at the most basic use of redirection, where we redirect the output of the
echo command to a file.
The result of the execution is as follows.
Here it is redirecting stdout to the file a.txt, which is equivalent to the following command.
The result of the execution is as follows.
Here we see that the redirection symbol
> defaults to redirecting
stdout, which is fd
1, to somewhere else.
If we want to redirect the standard error output
stderr, we just need to change the file descriptor
1 in the above command to the standard error output file descriptor
Redirecting to file descriptors
In some cases
stderr is programmatically controlled to write to the error log, so if we want to display the error on the screen while the command is running, we need to redirect the error output to the standard output stream.
Let’s try it first, here we don’t find a suitable command, so we take the
ls command to look at a directory that doesn’t exist, which will generate an error output.
Here the error is output to the screen by default, but I haven’t found a better program yet, so let’s assume it won’t be output to the screen.
Our guess here is to redirect
stdout , so we write
2>1 , let’s see if that works?
We see that instead of output, a file
1 is generated in the current directory, which means that if we just write
>1 it will be treated as a redirect to the file
At this point, our
& comes into play.
>& is the syntax for redirecting a stream to a file descriptor, so just now we should specify that we want to redirect to fd
1, which is
Here we can play independently.
Redirects the standard output to the standard error output.
We can even play a little more complicated.
Here the file descriptor
9 will be generated automatically, but removing the brackets will prompt an error.
In bash >4.0, a new redirect syntax has been introduced.
I haven’t learned this way of writing yet, I’ll update it later when I learn it
A little bit of high-end usage.
For formatting output, redirecting the standard output and error output streams to different processes, and finally aggregating them.
A new version of the grammar with the same effect.
Merge output files m and n:
n >& m.
Merge input files m and n:
n <& m.
Take as input the content between the start tag and the end tag:
Its function is to pass the content (document) between two EOFs as input to command.
- The delimiter at the end must be written in top space, with no characters before it and no characters after it, including spaces and tab indents.
- Spaces before and after the starting delimiter are ignored.
If we set bash with
set -o noclobber, then bash will not overwrite any files that already exist, but we can bypass this restriction with
Let’s look at the default case first
As expected, each redirect overwrites the original file
We set the
noclobber flag below
set -o noclobber
Then repeat the above to try it out.
We saw the bash prompt that it cannot overwrite an already existing file, and the actual result is the same.
How can we do the bypass? Let’s try
>| instead of
We find that we can overwrite the files that already exist at this point, and we look at the current settings.
noclobber is indeed turned on, so
>| does bypass this restriction.
set +o noclobber to turn off this restriction and prevent it from affecting our later use of
Other tidbits of knowledge
Redirecting to one place
If we want to redirect
stderr to the same place, how should we write it?
Which of the following two is the right one?
ls -ld /tmp /tnt 2>&1 1>a.txt
ls -ld /tmp /tnt 1>b.txt 2>&1
The first way to write
The second way to write
We can see that the second way of writing is correct.
Similarly, the following way of writing is also correct.
what happens if we redirect
stdout , and at the same time redirect
Will such nesting cause a crash?
We find that it all comes out of the standard output.
And the other way around?
We find that none of it comes out of the standard output, it comes out of the standard error output
a>&b b>&ais written in this nested way, and b is the output.
If you want to understand the functionality, check the official documentation with the following command
man -Len -Pless\ +/^REDIRECTION bash
Reference for this article: stack overflow