Data streams

    BashThis article is about working with data streams in bash . I tried to write it in the most accessible and simple language, so that even beginners in Linux could understand it.


    In one of my articles, we looked at recording sound in a file using the command:

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

    This command reads the file (device) / dev / audio using the cat command and redirects the information from it to the /tmp/my.sound file (using the> operator).

    Each program has 3 system threads: stdout , stderr , stdin .

    stdout


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

    $ ls
    bin incoming pub usr

    stderr


    Error output stream. If the program could not do everything as it should - it writes to this stream. For example, when rm tries to delete a nonexistent file:

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

    stdin


    Data input stream. But this is a rather interesting and convenient stream. For example, a web server uses it when it asks interpreters to execute scripts through CGI . We can also try:

    $ echo ' ' | php
    Hello world

    In this example, we came across an output redirection operator. We will dwell on it later.

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


    Thread redirection


    First, consider redirecting streams to files, devices, and other streams.

    $ ls > 1.txt

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

    $ cat 1.txt
    bin incoming pub usr

    Yes, everything was successfully recorded.

    Now try directing the stderr of the rm command:

    $ rm example.txt 2> 1.txt

    Here we used the stderr stream number (2). By default, the> operator redirects the stdout stream, which is number 1. To direct another stream, you must put its number before the> operator.

    We can direct some flows towards others:

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

    In this example, we directed the stdout stream to the 1.txt file, and then directed stderr to where stdout was directed using the & operator before the stream number.

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

    cd myproject
    find.

    The find command with a parameter. displays in stdout all subfolders and files that it finds in this folder and in all subfolders.

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

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

    Operator | redirects the stdout of one application to the stdin of the next. That is, all the lines found with 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 line should end with "/.svn".

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

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

    And again the new operator: ` . It takes stdout from the command that it surrounds and inserts into the given location as a string.

    It turns out that we requested all the files, selected folders with the name ".svn" from them 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. Correct the situation:

    find. | grep -e '/.svn$' | xargs the 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. The problem is solved.

    Everyone can help develop this series of articles, share their experiences. Welcome: http://www.linuxman.ru . Over time, I will transfer all changes to Wiki to Habr.

    Also popular now: