📜 ⬆️ ⬇️

Data streams

BASH This article is about working with data streams in bash . I tried to write it in the most accessible and simple language, so that it would be understandable even to newbies in Linux.


In one of my articles, we reviewed the recording of sound to a file using the command:

cat / dev / audio > /tmp/my.sound

This command reads the / dev / audio file (device) with the cat command and redirects information from it to the /tmp/my.sound file (using the> operator).
')
Each program has 3 system streams: stdout , stderr , stdin .

stdout


Standard output data stream for programs. For example, when we write the ls command, it lists the list of folders and files in this stream, which is displayed in our console:

$ ls
bin incoming pub usr

stderr


The error output stream. If the program could not do everything right - it is written in this thread. For example, when rm tries to delete a nonexistent file:

$ rm example.txt
rm: example.txt: No such file or directory

stdin


Data entry stream But this is quite an interesting and convenient stream. For example, it is used by the web server when it asks interpreters to execute scripts via CGI . We can also try:

$ echo '<? php echo "Hello world"; ?> '| php
Hello world

In this example, we encountered an output stream redirection operator. We will focus on it later.

More details:
http://ru.wikipedia.org/wiki/Standard_flows


Forwarding flows


To begin, consider the redirection of streams to files, devices, and other streams.

$ ls > 1.txt

In this example, we sent the stdout of the ls command to the file 1.txt. We read it:

$ cat 1.txt
bin incoming pub usr

Yes, everything successfully recorded.

Now let's try to send the stderr of the rm command:

$ rm example.txt 2> 1.txt

Here we used the stream number stderr (2). By default, the> operator redirects the stream to stdout, which has the number 1. To send another stream, you need to put its number in front of the> operator.

We can direct some flows towards others:

$ rm exmple.txt > 1.txt 2> & 1

In this example, we sent the stdout stream to the 1.txt file, and then sent stderr to the same direction as stdout with the & operator before the stream number.

Now let's play with the stream of stdin. For example, I want to find all the ".svn" folders in a certain project and delete:

cd myproject
find.

Find command with parameter. lists to stdout all subfolders and files that it finds in this folder and in all subfolders.

Now we need to select only folders with the name ".svn":

find. | grep -e '/.svn$'

Operator | redirects one application's stdout to the next stdin. That is, all the lines found using find went to the grep command, which selects the lines according to certain conditions and displays them. Here, the condition is a regular expression that says that the string must end in "/.svn".

We have selected the necessary folders, it remains to delete them.

rm -Rf ` find. | grep -e '/.svn$' `

Again, the new statement: ` . It takes stdout from the command it surrounds and inserts at that place as a string.

It turns out that we requested all the files, selected folders with the name ".svn", and gave the result as arguments to the rm command. In this case, we will have problems if the file and folder names contain spaces. We correct the situation:

find. | grep -e '/.svn$' | xargs rm -Rf

Now we give the necessary files to the xargs command, which calls rm -Rf and uses its stdin line-by-line as parameters. Problem solved.

Everyone can help the development of this series of articles, to share their experiences. Welcome to: http://www.linuxman.ru . All changes to the wiki, I will eventually transfer to Habr.

Source: https://habr.com/ru/post/55136/


All Articles