Look at the previous section: Linux Shell Data Redirection (input redirection and output redirection) detailed analysis It is estimated that some friends are dizzy, so complex redirect. This time we'll take a look at the pipe command. Shell pipe, it can be said that the usage is much simpler.
The pipe command operator is: "|", which can only handle the correct output information from the previous instruction, that is, the standard output information, for the Stdandard
Error information does not have direct processing capability. Then, pass it to the next command, as the standard input standard inputs.
Instructions for piping command use:
First look at the following figure:
Command1 the correct output, as Command2 input and then comand2 output as, comand3 input, comand3 output will be directly displayed on the screen.
After pipeline: The correct output of Comand1,comand2 does not appear on the screen
Attention:
1, pipe command only to handle the correct output of the previous command, do not handle error output
2, Pipeline command to the right, you must be able to receive the standard input stream command to the line.
Instance:
[chengmo @ centos5 shell] $ cat test.sh | grep -n 'echo'
5: echo "very good!";
7: echo "good!";
9: echo "pass!";
11: echo "no pass!";
#Read test.sh file content and forward it to grep as input
[chengmo @ centos5 shell] $ cat test.sh test1.sh | grep -n 'echo'
cat: test1.sh: no such file or directory
5: echo "very good!";
7: echo "good!";
9: echo "pass!";
11: echo "no pass!";
#cat test1.sh does not exist, the error output is printed to the screen, and the correct output is sent to grep through the pipe
[chengmo @ centos5 shell] $ cat test.sh test1.sh 2> / dev / null | grep -n 'echo'
5: echo "very good!";
7: echo "good!";
9: echo "pass!";
11: echo "no pass!";
#Redirect test1.sh not found error output to / dev / null file, send correct output to grep
[chengmo @ centos5 shell] $ cat test.sh | ls
catfile httprequest.txt secure test testfdread.sh testpipe.sh testsh.sh testwhile2.sh
envcron.txt python sh testcase.sh testfor2.sh testselect.sh test.txt text.txt
env.txt release sms testcronenv.sh testfor.sh test.sh testwhile1.sh
#Read the content of test.sh and send it to the ls command through the pipe. Because ls does not support standard input, the data is discarded.
Here The example is the verification of the above 2 points of attention. Action to receive standard input commands can be used as pipe to the right. Otherwise, the data is discarded during delivery. Commonly used as the receive data pipeline commands are: Sed,awk,cut,head,top,less,more,wc,join,sort,split and so on, are some text processing commands.
Differences between pipe commands and redirects
The difference is:
1, the left of the command should have standard output | The command on the right should accept the standard input
The command on the left should have standard output > right can only be a file
The command on the left should require standard input < The right can only be a file
2, the pipeline triggers two child processes to execute "|" On both sides of the program; redirects are performed within a process
These are a lot of online summary, in fact, as long as the use of more clearly, there must be a different description of their own.
Instance:
#Can convert each other
#Enter redirect
[chengmo @ centos5 shell] $ cat test.sh | grep -n 'echo'
5: echo "very good!";
7: echo "good!";
9: echo "pass!";
11: echo "no pass!";
# "|" The pipe must be a shell command on both sides
[chengmo @ centos5 shell] $ grep -n 'echo' <test.sh
5: echo "very good!";
7: echo "good!";
9: echo "pass!";
11: echo "no pass!";
# "Redirect" symbol, only files (normal files, file descriptors, file devices) on the right
[chengmo @ centos5 shell] $ mail -s 'test' 8292669@qq.com <test.sh
[chengmo @ centos5 shell] $ cat test.sh | mail -s 'test' 8292669@qq.com
#The above two are the same, and send the content of test.sh to the specified mailbox.
[chengmo @ centos5 shell] $ (sed -n '1, $ p' | grep -n 'echo') <test.sh
5: echo "very good!";
7: echo "good!";
9: echo "pass!";
11: echo "no pass!";
#This script is more interesting. Because the front is a pipe, the test.sh content needs to be redirected to sed later, and then the output of sed passes through the pipe and is input to grep. The "()" operator must be enclosed in the front. Commands enclosed in single brackets can be considered as one command. Without parentheses test.sh is the input for grep.
#The above one is equivalent to this
[chengmo @ centos5 shell] $ sed -n '1, $ p' <test.sh | grep -n 'echo'
5: echo "very good!";
7: echo "good!";
9: echo "pass!";
11: echo "no pass!";
#The redirection operator is checked first before the shell command is parsed (a command must be checked for its input and output before execution, that is, whether the 0,1,2 device is ready), so the priority will be the highest
[chengmo @ centos5 shell] $ sed -n '1,10p' <test.sh | grep -n 'echo' <testsh.sh
10: echo $ total;
18: echo $ total;
21: echo "ok";
#Haha, this grep accepts pipe input and testsh.sh input. Is it acceptable for both? The "<" operator just said will take precedence. Before the pipe sends data, grep binds the testsh.sh input, so the output of the sed command is discarded. Be careful to use here
#Output redirection
[chengmo @ centos5 shell] $ cat test.sh> test.txt
[chengmo @ centos5 shell] cat test.sh | tee test.txt &> / dev / null
#Save the results to a file through a pipe. You also need to use the command tee. It writes the standard input to the file test.txt, and then copies the standard input to the standard output (stdout), so it redirects to / dev / null. Do not display output
# ">" Output redirection is usually at the far right of the command. If you receive the command on the left, the output is redirected to the specified file. Can also be used in the middle of a command.
[chengmo @ centos5 shell] $ ls test.sh test1.sh testsh.sh 2> err.txt | grep 'test'
test.sh
testsh.sh
Below the directory: test, testsh files, test1.sh does not exist, so the error output of the ls command is input to err.txt and the correct output is also sent to the grep command through the pipe.
[chengmo @ centos5 shell] $ ls test.sh test1.sh testsh.sh &> err.txt | grep 'test'
#The print result is empty this time, & represents the correct and error output are input to err.txt, and the data is still passed through the pipeline to the bottom, so nothing is displayed.
# Likewise ">" Output redirection, the priority is also parsed first. When a command has this character, it will be bound to the standard output of the left command. Ready for this, just wait for the command to execute the output data and it will start receiving
In summary:
As can be seen from the example above, redirects and pipelines can be used in many cases, in fact, in the shell, often "all roads lead to Rome." Generally, if the command is passed between the parameters, or the pipeline is good, if the processing output needs to be redirected to the file, or with a redirect output better.
Command execution order can be seen: Linux Shell wildcard, metacharacters, escape character usages
Shell script receive pipeline input
Interesting question:
Since the action pipeline receives commands and needs to be able to receive standard input, can our shell script emit such a basic program? (as you often see, there are some system commands as pipeline receivers)
Instance (testpipe.sh):
#! / bin / sh
if [$ # -gt 0]; then
exec 0 <$ 1;
#Determine whether to pass parameters: file name, if passed in, bind the file to standard input
fi
while read line
do
echo $ line;
done <& 0;
#Read content through standard input loop
exec 0 &-;
#Unbind standard input
Run Result:
[chengmo @ centos5 shell] $ cat testpipe.txt
1, t, est pipe
2, t, est pipe
3, t, est pipe
4, t, est pipe
# testpipe.txt is just the test text that needs to be read
[chengmo @ centos5 shell] $ cat testpipe.txt | sh testpipe.sh
1, t, est pipe
2, t, est pipe
3, t, est pipe
4, t, est pipe
# Read testpipe.txt via cat and send to testpipe.sh standard input
[chengmo @ centos5 shell] $ sh testpipe.sh testpipe.txt
1, t, est pipe
2, t, est pipe
3, t, est pipe
4, t, est pipe
# testpipe.sh Read file contents by access file name
by Access to the filename