A pipe or pipe is actually a pipeline available for UNIX / Linux and very practical. But to fully understand what a pipe is, you should know that in a * nix environment it has 3 built-in data streams. That, for those who do not know, means that the data can travel to or from three points.
Then you will understand this in a better way, but what I want to make clear to you now is that with a pipeline what you can do is channel from one of those points to others. This allows taking the output or result that a program throws towards the input of another for that one to use, etc. I will try to explain it with some practical examples that will help you understand it very well.
Those points I was talking about or data streams, are:
- stdin: corresponds to 0 and is the standard input. Generally, the standard input for a * nix system is the keyboard. That is, what you type will be the information used. She has a special device associated with it which is / dev / stdin.
- stdout: identified with 1, it is the standard output. Usually it corresponds to the monitor or screen of your computer, which is where you can see the information. For example, when you run an ls command the list of contents will be displayed on the screen, right? The associated device is / dev / stdout.
- stderr: identified with 2, it is the standard error output, for when an error occurs in a program. The associated device is / dev / stderr.
With a pipeline you can make the standard output or stdout of one command pass directly to the standard input of another. That is, you can make one program feed another. Instead of using keyboard-entered parameters, a pipe delivers the information generated by the previous command through this pipeline represented by the |
With the examples you will understand it better. Suppose you want to list the contents of a directory, but you are only interested in seeing the names that match the word doc. So you could use a pipeline to pipe the output of ls into the input of the grep filter to tell it to only display the ones that match that pattern:
ls -l | grep doc
So instead of showing you all the names, it just shows you the ones that really interest you. You can do the same with the content of a file. Imagine that you only want to see the information of the processes named firefox and not all:
ps aux | grep firefox
Instead of showing all the output of the ps program on the screen (stdout), what it does is channel it towards the input of the grep filter and only shows in the output what corresponds to the firefox pattern in this case ...
If you want, you can use various pipes to bring the output of one command to the input of another second command, and the output of that second to the input of a third, and so on. For example:
cat libro | grep love | more
As you see, the possibilities are many, all that you can imagine and are allowed. Even show only the first and last lines of a file, count the lines that enter wc that come from the list, and even sort them:
cat listado | head cat listado | tail cat listado | wc -l cat listado | sort
You can also work with errors with | & and for example look for the word alert in the output of a script if it fails:
./miscript |& grep alerta
And finally, there are two commands closely linked to the pipes that are tee and xargs and that they can further extend the possibilities of these. In the case of tee, what it will allow is to show the result of the previous program on the standard output so that you can see it, and in addition to that, it can pipe it to another file. An example would be if you list the contents of a directory and want to see the output of ls -l at the moment and also have it saved in a file listing.txt:
ls -l | tee listado.txt
If you don't use tee, you won't be able to see the output on your console ...
Y xargs it is even more interesting in some cases. In this case it is able to build a command from the standard input it receives through the pipeline. In other words, it is capable of capturing everything that a previous program has launched through its output and that reaches xargs through the pipeline to pass it to another command as arguments.
Still don't get it? You will see it much better with an example. Imagine you want to remove all the damn thumbs.db files from a directory, disk, or partition. If there are many, it may be impossible to go one by one with the rm command to delete them manually. But with xargs you can automate everything. And you can do it using find to locate them, send the output through the input of xargs and this in turn will give rm the names as arguments. Therefore, all the located ones will be deleted automatically:
find ./ -name "thumbs.db" | xargs rm
For example, suppose that find locates /home/name/thumbs.db, /media/test/thumbs.db, and /tmp/thumbs.db. Well, xargs is going to deliver them to rm as if they were arguments. That is, as if we had executed: rm /home/name/thumbs.db, then rm /media/test/thumbs.db and then rm /tmp/thumbs.db.