1. Basic concepts (this is the prerequisite for understanding the following knowledge. please be sure to understand it)
A, I/O redirection is usually related to fd, and shell FD is usually 10, that is, 0 ~ 9;
B. There are three commonly used FD types: 0 (stdin, standard input), 1 (stdout, standard output), and 2 (stderr, standard error output ), the default value is related to keyboard, monitor, and monitor;
C. Use <to change the reading data channel (stdin) so that it can read from the specified file;
D. Use> to change the output data channel (stdout, stderr) and output it to the specified file;
E and 0 are the default values of <, so <and 0 <are the same. Similarly,> and 1> are the same;
F. In Io redirection, The stdout and stderr pipelines are prepared before reading data from stdin;
G. Pipeline "|" (pipe line): stdout of the previous command receives stdin of the next command;
H. The Tee Command copies stdout to the file without affecting the original I/O;
I. Bash (Ksh) Command Execution Process: Analysis command-variable evaluate-command substitution ("and $ ()-redirect-Wildcard expand-confirm path-Execute Command;
J. ()
Group is placed in sub-shell for execution, also known as nested
Sub-shell: inherits standard input, output, and error plus from the parent shell.
Any other open file descriptors.
K. EXEC command: It is often used to replace the current shell and restart a shell. In other words, there is no starting shell. When you use this command, any existing environment will be cleared. When exec operates on file descriptors, it is only in this case that exec will not overwrite your current shell environment.
2. Basic Io
CMD> file: redirects stdout to the file;
CMD> file: redirects stdout to the file (append );
CMD 1> Fiel redirects stdout to the file;
CMD> file 2> & 1 redirects stdout and stderr together to the file;
CMD 2> file: redirects stderr to the file;
CMD 2> file redirects stderr to the file (append );
CMD> file 2> & 1 redirect stderr and stderr together to the file (append );
CMD <File> the file2 cmd command uses the file as stdin and the file2 file as stdout;
Cat <> file: open the file in read/write mode;
CMD <file cmd command uses file as stdin;
CMD <delimiter here document, read from stdin until the delimiter Delimiter is encountered.
3. Advanced Io
> & N use the system to call DUP (2) copy the file descriptor N and use the result as the standard output;
<& N standard input copied from file descriptor N;
<&-Disable the standard input (keyboard );
> &-Disable standard output;
N <&-indicates that N is disabled;
N> &-indicates that output N is disabled;
All the above forms can lead to a number. In this case, the created file descriptor is specified by this number rather than the default 0 or 1. For example:
... 2> run a command in file and direct the error output (file descriptor 2) to file.
... 2> & 1 run a command and merge its standard output and output. (Strictly speaking, file descriptor 2 is created by copying file descriptor 1, but the effect is usually that two streams are merged .)
We
2> & 1 for details: 2> & 1, that is, fd2 = fd1. This does not mean that the value of fd2 is equal to the value of fd1, because>
Is to change the data channel sent, that is, to change the "data output channel" of fd2 to fd1
"Data output channel ". In this case, this change seems to have no effect, because the default output of fd2 and the default output of fd1 are both monitor, the same!
However, when fd1 is another file or even another FD, this has a special purpose. Be sure to understand this.
Exec 0 exec 1> outfilename # open the file outfilename as stdout.
Exec 2> errfilename # open the file errfilename as stderr.
Exec 0 <&-# disable fd0.
Exec 1> &-# disable fd1.
Exec 5> &-# disable fd5.
Q: What are the consequences of disabling fd0, fd1, and fd2? What is the difference between restoring fd0, fd1, and fd2 and disabling fd0, fd1, and fd2? What are the codes? FD3 ~ Enabled ~ Fd9, after we use it, do you think it is to close them or restore them?
The following is a prompt (the example is from the Cu post. If you forget the source, add it in the future ):
Exec 6> & 2 2> ver Command> DEV/null & Exec 2> & 6 # restore fd2 |
4. Simple examples
A, stdout, and stderr are both sent to egrep through the pipeline:
(ls you no 2>&1;ls yes 2>&1) 2>&1|egrep * >file (ls you no 2>&1;ls yes 2>&1)|egrep * >file (ls you no;ls yes) 2>&1|egrep * >file |
In this example, note the following:
Explain the command execution sequence and
Pipeline "|": Before executing the command, you must perform redirection and connect the stdout of the nested sub-shell to the stdin of the egrep command.
The nested sub-shell can be considered as a command by adding () to the two commands in. Its fd1 has been connected to "|" and sent to egrep.
2> In & 1, fd2 = fd1, that is, fd2 is sent to the pipeline "|" like fd1.
B,
Nothing is sent to egrep through a pipeline, and all is sent to monitor. (Ls you no 2> & 1; LS Yes
2> & 1)> & 2 | egrep *> file. Although fd2 is transferred to fd1 in (),
> & 2. All results are sent to the monitor. Please understand:
(Ls you no 2> & 1) 1> & 2 | egrep *> file # sent to monitor Ls you no 2> & 1 1> & 2 | egrep *> file # send to MPs queue "|" Ls you No 1> & 2 2> & 1 | egrep *> file # sent to monitor |
5. Intermediate order example
Condition: stderr sends the message to egrep through the pipeline, and the correct message is still sent to monitor (unchanged)
Exec 4> & 1; (ls you no 2> & 1 1> & 4 4> &-; LS Yes 2> & 1 1> & 4 4> &-) | egrep *> file; Exec 4> &- Or Exec 4> & 1; (ls you no; LS yes) 2> & 1 1> & 4 4> &-| egrep *> file; Exec 4> &- |
If two conditions are added:
(1) concurrent operation of cmd1 and cmd2 is required;
(2) Assign the return value of cmd1 to the variable ss.
Then:
exec 3>&1;exec 4>&1 ss=$(((ls you no 2>&1 1>&3 3>&-;echo $? >&4)|egrep * >file) 4>&1) exec 3>&-;exec 4>&- |
Note:
Exec
3> & 1; 4> & 1 create FD3, which is used to set the fd1 in the following ls Statement (sub-shell)
Restore to fd1, that is, output to monitor, you can regard FD3 as the initial fd1 hard disk backup (that is, output to monitor); Create fd4, and then use it to save the return of LS
Echo $ ?), You can think of fd4 as a store for computing "Echo $?" during the test ?" Draft paper;
(Ls you no
2> & 1 1> & 3 3> &-; echo $? > & 4)
Remember the sub-shell and pipeline mentioned above. This command First inherits from fd0, fd1, fd2, FD3, and fd4. It is located before the pipeline, so before running the command
The fd1 of shell itself is connected to the pipeline "|. However, the condition is that stderr is sent to egrep through the pipeline, and stdout is still output to monitor.
Therefore, through 2> & 1, The fd1 pipeline of the sub-shell is "sent" to "fd2, so the stderr in the sub-shell is sent to the pipeline" | ".
1> & 3. Restore the previous "hard disk backup" to the fd1 of the sub-shell, so the fd1 in the sub-shell is sent to monitor. Pass 3>
&-, Close 3; then run echo $? , The original output value should be sent to the pipeline, and the output will be sent through> & 4
"Draft paper" fd4, left for backup.
(Ls you no
2> & 1 1> & 3 3> &-; echo $? > & 4) | egrep *
> File) So stderr sends egrep through the pipeline, and stdout sends it to monitor. However, there is also fd4. Where does it go?
$ (Ls you no 2> & 1 1> & 3 3> &-; echo $?
> & 4) | egrep *> file) 4> & 1) the last 4> & 1 means to redirect fd4
Fd1. However, because it is output in $ (), its value is assigned to the variable ss. Disable FD3 and fd4 in the last line.
6. Advanced examples
Command cmd1, cmd2, cmd3, IPv4. how to use one-way pipeline to complete the following functions:
1. Execute all commands in parallel.
2. stdin is not required for cmd1 and cmd2.
3. stdout of cmd1 and cmd2 is directed to stdin of cmd3.
4. stderr of cmd1 and cmd2 is directed to stdin of limit 4.
5. stdout of cmd3 is directed to file a and stderr is directed to the screen.
6. stdout of IPv4 is directed to file B, and stderr is directed to the screen.
7. The return code of cmd1 is assigned to variable S.
8. Temporary files cannot be used.
Solution:
exec 3>&1; exec 4>&1 s=$(((((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3> &1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 4>&1) exec 3>&-; exec 4>&- |
This
I explained it step by step (it's complicated and I feel like I have understood it. After a while, I will see it again. The brain is still blank for a few minutes ~~~, I did not expect it to be clear. Exec 3> & 1;
Exec 4> & 1 the previous example shows that FD3 is created, fd1 is restored for cmd1, and
Restore fd2, create fd4, and save "Echo $ ?" The "draft" of the output value ".
The first pair of parentheses: (cmd1
1> & 3; echo $? > & 4) and the following (first) pipelines. In the first bracket (sub-shell), its fd1 has been connected
The pipeline is in progress, so use FD3 to restore fd1 to normal and prevent it from running in the pipeline; cmd1 here does not have stdin, and then save the return code of cmd1 to fd4.
Second pair of brackets: (cmd1
1> & 3; echo $? > & 4) | cmd2) 3> & 1 and later (second) pipelines. Previous
Fd1 is no longer sent to cmd2, and fd2 is not sent by default, so cmd2 does not have stdin, so in the second pair of brackets: cmd1 and cmd2
Stdout, stderr is the default output, always encounter
Until "3> & 1. Note: "3> & 1" first shows a command in the second pair of brackets. When they encounter the second pipe, their fd1 is connected to the pipe.
"|". Due to the role of "3> & 1", fd1 of the sub-shell is sent to FD3, so all FD3 outputs are
"Stream to" cmd3, and because of the inheritance relationship (inheriting the first line of command), FD3 is actually the stdout of cmd1 and cmd2, so "cmd1 and cmd2
Stdout to stdin of cmd3"
Brackets 3: (cmd1
1> & 3; echo $? > & 4) | cmd2) 3> & 1 | cmd3>
2> & 3) 2> & 1 and the third MPs queue. The stdout of cmd1 and cmd2 has been directed to
Stdin. After processing, cmd3> A means to send its stdout to
File. 2> & 3 indicates that the error output of cmd3 recovery is FD3, which is sent to monitor. Therefore, "The stdout of cmd3 is directed to the file.
A, stderr
To the screen ". If "2> & 3" is not available, the error output of cmd3 will interfere with the error output of cmd1 and cmd2, so it is required! Note that after the third pair of parentheses
"2> & 1" |, The fd1 of its sub-shell is connected to the pipeline "|", but the sub-shell fd1 is generous and sent to fd2, so fd2
Connect the MPs queue. Do you still remember the previous cmd1 and cmd2? Their stderr never moved. So here, the fourth command "limit 4" is sent through the pipeline.
. That is, "stderr of cmd1 and cmd2 is directed to stdin of limit 4 ". It is relatively simple later. When 4> B indicates "when 4"
Stdout is directed to file B, and stderr is directed to the screen (default )"
Parentheses (cmd1)
1> & 3; echo $? > & 4) | cmd2) 3> & 1 | cmd3>
2> & 3) 2> & 1 | limit 4> B) and the next 4> & 1. Four pairs of brackets
Fd1 and fd2 are all processed. But remember the previous "echo $?
> & 4 "is the draft paper? "4> & 1" is used to "Send the content on the draft to monitor", but because there is still $ ()
Package it ". Therefore, the value is assigned to the variable "S ".