Linux I / O redirection. Editing input

Having worked in Linux for some time, having typed the commands in the command line, Methodius came to the conclusion that some convenience would not interfere with communicating with the shell. One of these conveniences is the ability to edit the input line using the key Backspace(delete the last character), "^ W" (delete a word) and "^ U" (delete the whole line) - provided by the Linux terminal itself. These commands work for any line-by-line input: for example, if you run cat without parameters, it will immediately display the lines you enter from the terminal. If for some reason garbage has got into the line on the screen, you can press "^ R" ( r edraw) - the system will output to new line the contents of the input buffer.

Methodius did not forget that cat without parameters should be terminated with the "^ D" command (end of input). This command, like the previous ones, is interpreted by the system when entered from the terminal. The system converts some other control characters (for example, "^ C" or "^ Z") into signals... In fact, all control characters interpreted by the system can be reconfigured using the stty command. Full list configurable is given by the stty -a command:

$ stty -a localhost 38400 baud; rows 30; columns 80; line = 0; intr = ^ C; quit = ^ \; erase = ^ ?; kill = ^ U; eof = ^ D; eol = ; eol2 = ; start = ^ Q; stop = ^ S; susp = ^ Z; rprnt = ^ R; werase = ^ W; lnext = ^ V; flush = ^ O; min = 1; time = 0; -parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8 opostrnolcu on onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

Example 1... Terminal line settings

Seeing such vast possibilities, Methodius immediately set about reading the manual (man stty), but he found not so much useful in it. Of the control characters (lines from the second to the fourth) interesting are "^ S" and "^ Q", with the help of which you can, respectively, pause and resume output to the terminal (if a lot of text has already been displayed, but you do not have time to read it). You will notice that the erase setting corresponds to the control character returned by the key Backspace it is the Linux virtual console - “^? ". On many terminals, the key Backspace returns another character - "^ H". If nessesary override setting erase, you can use the command "stty erase ^ H", and "^ H" (for convenience) is allowed to enter as two characters: "^" and "H".

Finally, to deprive the transferred symbol of its control functions (if, for example, it is required to transfer to the program for input symbol with code 3, that is, "^ C"), immediately before entering this character, you need to issue the command "^ V" (lnext):

$ cat | hexdump -C Now press Ctrl + C $ cat | hexdump -C Now Ctrl + V, Ctrl + C, enter and Ctrl + D ^ C 00000000 f4 c5 d0 c5 d2 d8 20 43 74 72 6c 2b 56 2c 20 43 | Now Ctrl + V, C | 00000010 74 72 6c 2b 43 2c 20 45 6e 74 65 72 20 c9 20 43 | trl + C, enter and C | 00000020 74 72 6c 2b 44 03 0a | trl + D .. | 00000027

Example 2... Escaping control characters

Here Methodius interrupted, as he intended, the work of the first cat. At the same time, it did not even reach hexdump, a filter that converts the input stream to hexadecimal representation, because cat did not have time to process a single line. In the second case, "^ C" after "^ V" lost its control meaning and was displayed when typing. With the "-C" switch, hexdump also prints the text representation of the input stream, replacing non-printable characters with periods. Thus, both "^ C" (ASCII code 03) and the returned Enter end-of-line character (ASCII code 0a, decimal 12). Neither "^ V" nor "^ D" entered hexdump, of course: they were processed by the system as managers.

Other stty settings relate to the processing of text when outputting to and from the terminal. They are interesting only in the sense that when you change them, it becomes inconvenient to work with the command shell. For example, the echo setting determines whether the system will display whatever the user enters on the screen. When echo is on, pressing any alphanumeric keys(character input) causes the system (tty type device) will deduce this character to the terminal. The setting is disabled when the password is entered from the keyboard. At the same time, it is difficult to shake off the feeling that keyboard input is not happening. The situation is even worse with settings consisting of chunks like "i", "o", "cr" and "nl". These settings control the conversion on input and output of the historical two-character end-of-line designation to one adopted in Linux. It may happen that the key Enter terminal returns just the wrong end-of-line character, and conversion is disabled. Then instead of Enter use "^ J" - the character that actually matches the end of the line.

In all cases, when the terminal is in an incomprehensible state, it does not respond to Enter, does not show input, does not delete characters, displays text in "steps", etc., it is recommended to "cure" the terminal settings using stty sane - a special form of stty that resets the terminal settings to some usable state. If an incomprehensible state of the terminal occurred once, for example, after an abnormal termination screen program(vim editor or mc shell), you can use the reset command. She reconfigures the terminal to full compliance with the system configuration (specified in the / etc / inittab file, see the lecture Stages of System Booting) and terminfo.

If the terminal is behaving strangely, the sequence "^ J stty sane ^ J" can cure it!

Command line editing

Without even studying specifically the capabilities of the command shell, Methodius actively used some of them that were not available when entering text. the majority utilities (in particular, neither cat nor hexdump). It's about the keys Left arrow and Right arrow, with which you can move the cursor along the command line, and the key Del removing the character under cursor, not behind it. In the Terminal and Command Line lecture, he already made sure that these commands work in bash, but do not work for cat. Moreover, for a simple shell - sh - they don't work either.

Hence, the editor's capabilities command line are specific to different command shells. However, the most essential editing commands are supported in all flavors of the shell in a similar way. According to Gurevich, "all kinds of Linux have bash, and if you are experienced enough to install and configure packages, you can install zsh, it has more features than one person could ever need." Therefore, Methodius began studying the bash documentation, which turned out to be a difficult task, since he counted more than eight and a half thousand lines in bash.info. Even so much has been written about editing the command line that it's hard to read at once.

Trying to find out everything about working in the command line by "swoop" was of some benefit. Firstly, you can move in the command line not only one character forward and backward, but also according to the words: commands ESCF / ESCB or Alt + F / Alt + B respectively (from f orward and b ckward), the keys also work & home & and & end &, or, equivalently, "^ A" and "^ E". And secondly, in addition to working with one command line, there are many other conveniences that will be discussed in this lecture.

Command history

Methodius also actively used two other arrow keys - up and down - without suspecting that he was using this very powerful bash mechanism - working with team history... All commands typed by the user, bash remembers and allows you to refer to them later. Up arrow (you can also use "^ P", p revious), the list of submitted commands "scrolls" from the last to the first, and the down arrow ("^ N", n ext) - back. The corresponding command is displayed on the command line as just typed, it can be edited and submitted to the shell (it is not necessary to adjust the cursor to the end of the line).

If you need to get some old team from history, it's easier not to drive the history list with arrows, but search in it using the command "^ R" ( r everse search). This displays a special hint ("(reverse-i-search)"), the search substring (surrounded by `and" symbols) and the last command in history that contains this substring:

$ ^ R | (reverse-i-search) `": i | (reverse-i-search) `i": ls i n | (reverse-i-search) `in": info f | (reverse-i-search) `inf": info o | (reverse-i-search) `info": info ^ R | (reverse-i-search) `info": man info ^ R | (reverse-i-search) `info": info "(bash.info.bz2) Commands For History"

Example 3... Search command history

The example shows the characters entered by Methodius (on the left before "|") and the contents of the last line of the terminal. These are "frames" of work with the same line, showing how it changes as you type. Typing "info", Methodius continued searching for this substring, repeating "^ R" until he came across the command he needed containing the substring "info". It remains only to transfer it to bash using Enter .

So that the history of commands can be saved between bash writes it to the .bash_history file in the user's home directory. This is done at the moment completion shells: the history accumulated during the operation is appended to the end of this file. The next time bash starts, it reads the entire .bash_history. The history is not stored forever, the number of memorized commands in .bash_history is limited (usually 500 commands, but this can be reconfigured).

Abbreviations

Searching through history is a handy tool: instead of typing a long command line, you can find and use it. but long-standing the team will have to be obtained with the help of a few "^ R" - or you may not find it at all if it has already been eliminated from there. In order to quickly replace short commands with long ones, you should use reductions(aliases). In the configuration files of the user's command interpreter, several abbreviations are usually already defined, a list of which can be viewed using the alias command without parameters:

$ alias alias cd .. = "cd .." alias cp = "cp -i" alias l = "ls -lapt" alias ll = "ls -laptc" alias ls = "ls --color = auto" alias md = "mkdir" alias mv = "mv -i" alias rd = "rmdir" alias rm = "rm -i"

Example 4... Viewing predefined abbreviations

Methodius had already encountered abbreviations in the Access Rights lecture, where the ls command refused to work in accordance with the theory. It turned out that on the ls command, instead of the / bin / ls utility, bash runs its own shortcut command, which turns into the ls --color = auto command. Re the interpreter does not process the substring "ls" that appeared in the command, in order to avoid an eternal loop. For example, the command ls -al becomes ls --color = auto -al as a result. Similarly, any command starting with rm becomes rm -i ( i nteractive), which Methodius is extremely annoying, because no deletion is complete without questions like “rm: delete a regular file` file "?».

$ unalias cp rm mv $ alias pd = pushd $ alias pp = popd $ pd / bin / bin ~ $ pd / usr / share / doc / usr / share / doc / bin ~ $ cd / var / tmp $ dirs / var / tmp / bin ~ $ pp / bin ~ $ pp ~ $ pp -bash: popd: directory stack empty

Example 5... Using abbreviations and pushd / popd

Methodius got rid of the annoying "-i" with the help of the unalias command, and at the same time introduced abbreviations for his favorite bash commands - pushd and popd. These commands, like cd, change the current directory.

They are named by analogy with the stack operations - push and pop.

The difference is that pushd stores all directories that the user makes current in a special list (stack). The popd command removes the last element of this stack, and makes the next-to-last directory the current directory. In addition, both commands dump the contents of the directory stack (the dirs command does the same). The bash cd command also works with the directory stack: it replaces its last element is new.

Abbreviation command An internal user-defined shell command. Usually replaces one longer command that is often used when working at the command line. Abbreviations are not inherited with the environment.

Completion of construction

Abbreviations let you type quickly commands, but do not affect names in any way files, which most often turn out to be the parameters of these commands. It happens that the typed line - the path to the file and the first few letters of its name - is enough for unambiguous indications of this file, because there are simply no more files on the entered path, whose name begins with these letters. In order not to add the remaining letters (and file names in Linux can be quite long), Gurevich advised Methodius to press the key Tab... And - lo and behold! - bash itself has completed the beginning of the file name to an integer (again, we will use the "frames" method):

$ ls -al / bin / base Tab | $ ls -al / bin / basename -rwxr-xr-x 1 root root 12520 Jun 3 18:29 / bin / basename $ base Tab | $ basename Tab | $ basename ex Tab | $ basename examples / Tab | $ basename examples / -filename-with- -filename-with-

Example 6... Using completion

Further more. It turns out that the name of the command can not be entered entirely: the shell will guess to complete the word it is typing just to the command, since this word is at the beginning of the command line. Thus, Methodius typed the command basename examples / -filename-with- in eight keystrokes ("base" and four Tab)! He did not have to enter the beginning of the file name in the examples directory, because there was only one file there.

By completing a line, bash may not print the entire line, but only that part of it that it has no doubts about. If further completion of construction can go several paths, then single press Tab will cause bash to squeak in confusion, and repeated - to the output under command line list of all possible options.

All terminals must be able to issue sound signal when outputting the control character "^ G". You do not need to run any additional programs: "Real" terminals have a built-in speaker, while virtual consoles usually use a system ("beeper"). As a last resort, it is allowed to attract the user's attention in other ways: for example, the screen terminal emulator writes "wuff-wuff" in the service line.

In this case, you need to prompt command shell continuation: add a few characters that determine which path the completion will take, and press again Tab .

Search keyword"Completion" in the bash documentation provided so much information that Methodius turned to Gurevich for help. However, he replied that he does not use bash, and therefore is not able to explain the intricacies of its configuration. If in bash there are several types of completion (by file names, by command names, etc.), then in zsh they as much as you like: there is a way to program any extension algorithm and specify a command line template in which this particular method will be applied.

Although usually, as mentioned, program I / O is associated with standard streams, there are special facilities in the shell for redirecting I / O.

5.5.1 Operators>,< и >>

The symbols " > ", "< " and " >> ". The most common use is to redirect the output of a command to a file. Here's an example:

$ ls -l> /home/jim/dir.txt

This command will save a list of files and subdirectories of the directory that was current at the time of the command execution in the file /home/jim/dir.txt ls; in this case, if the specified file did not exist, then it will be created; if it existed, it will be overwritten; if you want the command output to be appended to the end of an existing file, then instead of the symbol > use >> ... In this case, the presence of spaces before or after the characters > or >> is irrelevant and serves only for the convenience of the user.

You can direct the output not only to a file, but also to the input of another command or to a device (such as a printer). For example, to count the number of words in the /home/jim/report.txt file, you can use the following command:

$ cat /home/jim/report.txt> wc -w

and to print the file, use the command:

$ cat /home/jim/report.txt> lpr

As you can see, the operator > serves to redirect the output stream. With respect to the input stream, a similar function is performed by the operator < ... The above command example for counting the number of words in a specific file can be rewritten as follows (note the lack of command cat):

$ wc -w< /home/jim/report.txt

This type of redirection is often used in various scripts for commands that normally accept (or expect) keyboard input. In a script that automates some routine operations, you can give the command the necessary information from the file, which pre-recorded what you need to enter to execute this command.

Due to the fact that the symbols < , > and >> act on standard streams, they can be used not only in the usual way, as is usually done, but also in a slightly different way. So, the following commands are equivalent:

$ cat> file

$ cat> file

$> file cat

$> file cat

However, by itself (without any command for which the standard streams are defined) the redirection character cannot be used, so you cannot, for example, by typing

$ file1> file2

get a copy of a file. But this does not diminish the value this mechanism because standard streams are defined for any command. In this case, you can redirect not only standard input and output, but also other streams. To do this, you must specify the number of the redirected stream before the redirection symbol. The stdin standard input is numbered 0, stdout stdout is number 1, the standard error stream stderr is number 2. That is, the full format of the redirection command is (recall that spaces near> are optional):

command N> M

where N and M- standard stream numbers (0,1,2) or file names. The use of symbols in some cases < , > and >> without specifying the channel number or file name is possible only because instead of the missing number, the default is 1, that is, standard output. So, the operator > without specifying the number is interpreted as 1 > .

In addition to simple redirection of standard streams, it is also possible not only to redirect a stream to a particular channel, but to make a copy of the contents of a standard stream. This is done with a special character & , which is placed before the number of the channel to which the stream is redirected:

command N> & M

This command means that the output of channel number N is sent to both standard output and duplicated to channel numbered M... For example, in order for error messages to be duplicated on standard output, you must issue the command 2>&1, while 1>&2 duplicates stdout to stderr. This feature is especially useful when redirecting output to a file, since we then simultaneously see the messages on the screen and save them to the file.

5.5.2 Operator |

A special option for output redirection is piping (sometimes called a pipe or pipe). To do this, two or more commands, such that the output of the previous one serves as input for the next, are concatenated (or separated, if you prefer) with a pipe character - "|". In this case, the standard output stream of the command located to the left of the character | , goes to the standard input of the program to the right of the symbol | ... For example:

$ cat myfile | grep Linux | wc -l

This line means that the output of the command cat, that is, the text from the file myfile will be directed to the input of the command grep which will only highlight lines containing the word "Linux". Command output grep will, in turn, be directed to the input of the command wc -l, which will count the number of such lines.

Pipes are used to combine several small programs, each of which performs only certain transformations on its input stream, to create a generalized instruction that will result in some more complex transformation.

It should be noted that the shell simultaneously calls for execution all the commands included in the pipeline, starting a separate instance of the shell for each of the commands, so as soon as the first program starts to issue something to its output stream, the next command starts processing it. In the same way, each next command performs its own operation, waiting for data from the previous command and giving its results to the input of the next one. If you want a command to complete completely before executing the next one, you can use in one line as a pipe symbol | and semicolon ; ... Before each semicolon, the shell will pause and wait for all previous commands included in the pipeline to complete.

The exit status (a boolean value returned after the program terminates) from the channel is the same as the exit status returned by the last command in the pipeline. Before the first command of the pipeline, you can put a "!" Symbol, then the exit status of the pipeline will be logical negation the exit status of the last command. The shell waits for all pipeline commands to complete before setting the return value.

5.5.3 Filters

The last of the above examples (with the command grep) can be used to illustrate another important concept, namely a filter program. Filters are commands (or programs) that take the input data stream, perform some transformations on it, and output the result to standard output (from where it can be redirected somewhere else at the user's request). Among the filter commands are the commands already mentioned above cat, more, less, wc, cmp, diff, as well as the following commands.

Table 5.1. Filter Commands

Command

Short description

grep, fgrep, egrep

Searches the input file or data from standard input for lines containing the specified pattern and prints them to standard output

Replaces in the input stream all occurring characters listed in the given list with the corresponding characters from the second given list

comm

Compares two files line by line and outputs 3 columns to standard output: one contains lines that occur only in file 1, the second contains lines that occur only in file 2: and the third contains lines that appear in both files

Formats for printing text file or the content of stdin

sed

A string editor used to perform some transformations on the input data stream (taken from a file or from standard input)

A special filter is the command tee which splits the input stream, on the one hand directing it to standard output, and on the other to a file (whose name you must specify). It is easy to see that by its action the command tee similar to the redirection operator 1> & file.

The capabilities of filters can be significantly expanded by using regular expressions that allow you to organize, for example, a search in various, often very complex, patterns.

A lot could be said about redirection and filters. But this material is available in most books on UNIX and Linux, for example, Petersen [A1.4] and Kelly-Bootle [A1.8]. Therefore, we will restrict ourselves to what has been said, and proceed to consider the so-called environment or environment created by the shell.

V. Kostromin (kos at rus-linux dot net) - 5.5. I / O redirection, pipes and filters
  • Translation

If you're already comfortable with the basics of the terminal, you may already be ready to combine the commands you've learned. Sometimes executing shell commands one at a time is enough to solve a certain task, but in some cases, entering command after command is too tedious and irrational. In a situation like this, we will need some special characters like angle brackets.

For shell, interpreter Linux commands, these additional characters- not a waste of screen space. They are powerful teams that can tie together different pieces of information, separate what was previously integral, and do much more. One of the simplest, yet most powerful and widely used shell features is the redirection of standard I / O streams.

Three standard I / O streams

In order to understand what we are going to talk about here, it is important to know where the data that can be redirected comes from, and where it goes. There are three standard I / O streams in Linux.

The first is standard input. In the system, this is stream # 0 (since in computers the counting usually starts from zero). Stream numbers are also called descriptors. This stream represents some information passed to the terminal, in particular, instructions passed to the shell for execution. Typically, data enters this stream as the user enters it from the keyboard.

The second stream is standard output and is numbered 1. This is the stream of data that the shell outputs after doing something. Typically, this data ends up in the same terminal window where the command that caused it to appear was entered.

And finally, the third stream is the standard error stream, it has descriptor 2. This stream is similar to the standard output stream, in that what gets into it usually ends up on the terminal screen. However, it is, in its essence, different from standard output, as a result, these streams, if desired, can be controlled separately. This is useful, for example, in the following situation. There is a team that processes a large amount of data, performing a complex and error-prone operation. You want the payload that this command generates not to mix with error messages. This is accomplished thanks to separate redirection of output and error streams.

As you probably already guessed, redirecting I / O means working with the above streams and redirecting data to where the programmer needs it. This is done using the> and< в различных комбинациях, применение которых зависит от того, куда, в итоге, должны попасть перенаправляемые данные.

Redirecting the standard output stream

Suppose you want to create a file that will record the current date and time. To make things easier, there is a command, aptly named date, that returns what we want. Commands usually write data to standard output. In order for this data to appear in the file, you need to add the> symbol after the command, before the name of the target file. Before and after> must be blank.

When using redirection, any file specified after> will be overwritten. If there is nothing valuable in the file and its contents can be lost, it is permissible to use an existing file in our design. Usually it is better to use in similar case the name of a file that does not yet exist. This file will be created after the command is executed. Let's call it date.txt. The file extension after a period is usually not important, but extensions help keep things organized. So here's our command:

$ date> date.txt
This is not to say that this command itself is incredibly useful, however, based on it, we can already do something more interesting. Let's say you want to know how your traffic routes across the Internet to a certain endpoint change by recording the relevant data every day. In solving this problem, the traceroute command will help, which reports the details of the traffic route between our computer and the endpoint specified when invoking the command in the form of a URL. The data includes information about all routers through which traffic passes.

Since we already have a file with the date, it will be quite justified to simply attach the data received from traceroute to this file. To do this, you need to use two> symbols, one after the other. As a result, a new command that redirects the output to a file, but does not overwrite it, but adds new data after the old, will look like this:

$ traceroute google.com >> date.txt
Now we just have to change the file name to something more meaningful, using the mv command, which, as the first argument, is passed the original file name, and as the second - the new one:

$ mv date.txt trace1.txt

Redirecting standard input

Using the sign< вместо >we can redirect standard input by replacing it with the contents of the file.

Suppose you have two files, list1.txt and list2.txt, each containing an unsorted list of strings. Each of the lists has elements that are unique to it, but some of the elements in the list are the same. We can find the lines that are in both the first and second lists by using the comm command, but the lists must be sorted before using it.

There is a sort command that returns the sorted list to the terminal without saving the sorted data to the file it was taken from. You can send a sorted version of each list to new file using the> command and then using the comm command. However, this approach requires at least two commands, although the same can be done in one line without creating unnecessary files.

So, we can use the command< для перенаправления отсортированной версии каждого файла команде comm . Вот что у нас получилось:

$ comm<(sort list1.txt) <(sort list2.txt)
The parentheses here have the same meaning as in mathematics. The shell processes commands in parentheses first, and then everything else. In our example, we first sort the strings from the files, and then what happened is passed to the comm command, which then outputs the result of comparing the lists.

Redirecting standard error stream

Finally, let's talk about standard error stream redirection. This may be needed, for example, to create log files with errors or to combine in one file error messages and data returned by a command.

For example, what if you want to search the entire system for information about the wireless interfaces that are available to users who do not have superuser rights? To do this, you can use the powerful find command.

Typically, when a normal user runs the find command throughout the system, it will output both useful data and errors to the terminal. At the same time, the latter are usually more than the former, which makes it difficult to find what you need in the command output. The solution to this problem is quite simple: just redirect the standard error stream to a file using the command 2> (remember, 2 is a descriptor for the standard error stream). As a result, only what the command sends to standard output will be displayed:

$ find / -name wireless 2> denied.txt
What to do if you need to save the results of the team's work in separate file without mixing this data with error information? Since streams can be redirected independently of each other, we can add the command to redirect the standard output stream to a file at the end of our construction:

$ find / -name wireless 2> denied.txt> found.txt
Note that the first angle bracket comes with a number - 2>, and the second without it. This is because stdout has descriptor 1, and the> command will redirect stdout if no descriptor number is specified.

And finally, if you want everything that the command outputs to end up in one file, you can redirect both streams to the same place using the &> command:

$ find / -name wireless &> results.txt

Outcomes

Here we have analyzed only the basics of the stream redirection mechanism in the command interpreter Linux strings however, even the little you have learned today gives you almost unlimited possibilities. And by the way, like everything else when it comes to working in the terminal, mastering stream redirection takes practice. Therefore, we recommend that you start your own experiments with> and< .

Dear Readers! Did you know interesting examples using thread redirection in Linux to help newbies become more comfortable with this terminal trick?

One of the most interesting and useful topics for system administrators and new users who are just starting to understand how to work with the terminal is Linux I / O redirection. This feature of the terminal allows you to redirect the output of commands to a file, or the contents of a file to command input, combine commands together, and form command pipelines.

In this article, we will look at how I / O redirection is performed in Linux, what operators are used for this, and also where all this can be applied.

All the commands we execute return three kinds of data to us:

  • The result of command execution, usually text data requested by the user;
  • Error messages - inform about the process of command execution and unforeseen circumstances;
  • The return code is a number that allows you to evaluate whether the program worked correctly.

In Linux, all substances are considered files, including linux input / output streams - files. Each distribution has three main stream files that programs can use, these are defined by the shell and identified by the file descriptor number:

  • STDIN or 0- this file is associated with the keyboard and most commands get data to work from here;
  • STDOUT or 1- this is standard output, here the program sends all the results of its work. It is associated with the screen, or more precisely, with the terminal in which the program is running;
  • STDERR or 2- all error messages are output to this file.

I / O redirection allows you to replace one of these files with your own. For example, you can force the program to read data from a file into file system, not the keyboard, you can also output errors to a file, not to the screen, etc. All this is done using symbols "<" and ">" .

Redirect output to a file

Everything is very simple. You can redirect the output to a file using the> symbol. For example, let's save the output of the top command:

top -bn 5> top.log

The -b option makes the program run in non-interactive batch mode, and n - repeats the operation five times to get information about all processes. Now let's see what happened with cat:

Symbol ">" overwrites the information from the file if there is already something there. To add data to the end use ">>" ... For example, redirect the output to a linux file else for top:

top -bn 5 >> top.log

By default, the standard output file descriptor is used for redirection. But you can specify this explicitly. This command will give the same result:

top -bn 5 1> top.log

Redirect errors to file

To redirect error output to a file, you need to explicitly specify the file descriptor you want to redirect. For errors, this is number 2. For example, when trying to access the superuser directory, ls will give an error:

You can redirect standard error to a file like this:

ls -l / root / 2> ls-error.log
$ cat ls-error.log

To add data to the end of the file, use the same symbol:

ls -l / root / 2 >> ls-error.log

Redirect standard output and errors to a file

You can also redirect all output, errors, and standard output to a single file. There are two ways to do this. The first one, the older one, is to pass both descriptors:

ls -l / root /> ls-error.log 2> & 1

First, the output of the ls command will be sent to the ls-error.log file using the first redirection character. Further, all errors will be sent to the same file. The second method is simpler:

ls -l / root / &> ls-error.log

You can also use append instead of overwrite:

ls -l / root / & >> ls-error.log

Standard input from file

Most programs, except for services, receive data for their work through standard input. By default, standard input expects data from the keyboard. But you can force the program to read data from a file using the operator "<" :

cat

You can also immediately redirect the output to a file too. For example, let's re-sort the list:

sort sort.output

Thus, we redirect the linux input / output in one command.

Use of tunnels

You can work not only with files, but also redirect the output of one command as the input of another. This is very useful for performing complex operations. For example, let's display five recently changed files:

ls -lt | head -n 5

With the xargs utility, you can combine commands so that standard input is passed to parameters. For example, let's copy one file into several folders:

echo test / tmp / | xargs -n 1 cp -v testfile.sh

Here, the -n 1 option specifies that only one option should be substituted for one command, and the -v option to cp allows you to display detailed information about movements. Another command useful in such cases is tee. It reads data from standard input and writes to standard output or files. For example:

echo "Test tee working" | tee file1

Combined with other commands, these can be used to create complex instructions from multiple commands.

conclusions

In this article, we covered the basics of redirecting Linux I / O streams. Now you know how to redirect output to a linux file or output from a file. It is very simple and convenient. If you still have questions, ask in the comments!

Any program is an "automaton" designed for data processing: receiving one information at the input, it produces another as a result of its work. Although the incoming and / or outgoing information can be zero, that is, it can be simply absent. The data that is passed to the program for processing is its input, what it produces as a result of its work is output. The organization of the input and output for each program is the task of the operating system.

Each program works with data of a certain type: text, graphic, sound, etc. As you probably already understood, the main system management interface in Linux is a terminal, which is designed to transfer text information from the user to the system and vice versa. Since only text information can be entered from the terminal and displayed on the terminal, the input and output of programs associated with the terminal must also be text. However, the need to operate with textual data does not limit the possibilities of managing the system, but, on the contrary, expands them. A person can read the output of any program and figure out what is happening in the system, and different programs turn out to be compatible with each other, since they use the same type of data representation - text.

Commands and scripts can receive input in two ways: from standard input (associated with the keyboard) or from a file. A similar division exists when outputting data: the results of a command or script are sent to the terminal screen by default, but you can redirect them to a file. If errors occur during operation. messages about them are also displayed on the screen, the error stream can also be redirected to a file.

Let's first look at a couple of commands that you can use to organize I / O.

Standard Output Commands

Linux provides several commands for printing messages to standard output:

  • echo - Print a string to standard output.
  • printf - Print formatted text to standard output.
  • yes - Output duplicate text to standard output.
  • seq - Print a sequence of numbers to standard output
  • clear Clear the screen or window.

For example, when using the echo command, if you specify the control character \ c, then no newline will be made when the output is complete:

$ echo "What's your name? \ c"

What is your name? $

Here $ is the invitation character.

You can also compute the values ​​of shell variables and even other commands in a string. For example, the following command tells you what the home directory of the current user is ($ HOME environment variable) and which terminal it is connected to (the tty command is enclosed in backticks so that the interpreter will put the result of its execution in the string).

$ echo "Your home directory is $ HOME, you are connected to a terminal is` tty` "

Your home directory is / home / knoppix, you are connected to a terminal - / dev / tty1

Since double quotes in the shell interpreter have a special purpose, in order to include double quotes in the output string, you must cancel their special purpose with a backslash (\). This unassigns any special character.

For example, to display the line “/ dev / tty1” you need to run:

$ echo “\” / dev / tty1 \ ””

Input commands from standard input

The read command reads one line from the standard input stream and writes its contents to the specified variables. When specifying several variables, the first word is written to the first of them, the second - to the second, etc. in the last - the rest of the line.

The following script calls a separate read command to read each variable.


$ cat test
#! / bin / bash
echo "Name: \ s"
read name
echo "Last name: \ c"
read surname
echo “First name =” $ name “Last name =” $ surname

Then, to execute this script, you need to give the test file the right to execute: chmod 0755 test and run it. / Test. Result of execution: First name: Ivan Last name: Petrov First name = Ivan Last name = Petrov

STANDARD INPUT, OUTPUT AND ERROR STREAMS

Each program launched from the shell receives three open I / O streams:

Standard input (sldin) - standard output (sldout) - standard error output (stderr)

By default, these streams are associated with the terminal. Those. any program that does not use streams other than the standard ones will wait for input from the terminal keyboard, all the output of this program, including error messages, will occur on the terminal screen.

At the same time, with each process (command, script, etc.) executed in the shell, there are associated a number of open files, from which the process can read its data: and into which it can write them. Each of these files is identified by a number called a file descriptor, but the first three files are the default I / O streams:

File Descriptor
Standard input stream 0
Standard output stream 1
Standard error stream 2

In fact, 12 open files are created, but files with descriptors 0, 1, and 2 are reserved for standard input, output, and error streams. Users can also work with files with descriptors 3 to 9 (reserved).

The standard input stream file (sldin) has descriptor 0. From this file, processes extract their input. By default, the input stream is associated with the keyboard (device / dev / tty), but most often it comes through a pipe from other processes or from a regular file.

The standard output file (stdout) has descriptor 1. This file writes all the output of the process. By default, data is printed to the terminal screen (device / dev / tty), but it can also be redirected to a file or piped to another process.

The standard error stream (siderr) file has descriptor 2. This file records error messages that occur during command execution. By default, error messages are printed to the terminal screen (device / dev / tty), but they can also be redirected to a file. Why select a special file to log errors? The fact is that this is a very convenient way of separating the actual output data from the results of a command's work, as well as a good opportunity to effectively organize the maintenance of various kinds of log files.

A large number of utilities use only standard streams. For such programs, the shell allows you to independently redirect I / O streams. For example, you can suppress the output of error messages, set input or output from a file.

Those. when invoking commands, you can specify where to receive input and where to send output, as well as error messages. By default, unless otherwise stated, work with the terminal is implied: data is entered from the keyboard and displayed on the screen. But the shell has a redirection mechanism that allows you to associate standard streams with various files. In this case, when redirecting the standard error stream, you should specify the file descriptor (2). This is optional for input and output streams.

A useful special case of using the stream redirection mechanism is redirecting to / dev / null, which allows you to get rid of unnecessary messages on the screen. Empty files can be created using the same mechanism:

% cat myfile - will create an empty file myfile in the current directory.

/ dev / null is a special file representing the so-called. "Empty device". Writing to it is successful, regardless of the amount of "recorded" information. Reading from / dev / null is equivalent to reading the end of the EOF file.

Redirecting I / O Streams is carried out similarly to DOS (More precisely, the DOS OS adopted the thread redirection syntax from UNIX) using the symbols:

- redirecting the standard output stream
- redirecting the standard output stream in the post-write mode
- redirection of standard input stream
- receiving data from the standard input stream until a delimiter is encountered

However, unlike DOS, when creating a pipe between two processes, UNIX / Linux OS starts both processes simultaneously and transfers information through the system buffer (without intermediate writing to the hard disk). Thus, pipes on UNIX / Linux are a very efficient way to exchange. In the event of an overflow of the system buffer (for example, if the "transmitting" "program sends information to the channel faster than the" receiving "" program can process it), the OS automatically pauses the process that writes to the channel until the buffer is freed.

Most common call forwarding operators

# Syntax Description
1 command file Directs standard output to a new file

2 command 1 file Sends standard output to the specified file

3 command file Sends standard output to the specified file (attach mode)

4 command file 2 & 1 Sends standard output and error streams to the specified file

5 command 2 file Sends standard error to the specified file

6 command 2 file Sends standard error to the specified file (attach mode)

7 command file 2 & 1 Sends standard output and error streams to the specified file (attach mode)

8 command file1 file2 Receives input from the first file and directs the output to the second file

9 command file as standard input receives data from the specified file

10 command delimiter Receives data from standard input until a delimiter is encountered

11 & m command Receives data from file descriptor m as standard input

12 & m command Directs standard output to file descriptor m

The n & m operator redirects the file with descriptor n to the same location as the file with descriptor m. There can be several such operators on the command line, in this case they are evaluated from left to right.

The exec command and using file descriptors

The exec command replaces the current shell with the specified command. It is usually used to close the current interpreter and start another. But it also has other uses.

For example, a command like

The exec file makes the specified file the standard input for all commands. Perform it in
interactive mode makes no sense - it is intended for use in scripts,
so that all commands following it read their input from the file. In this case
at the end of the script there must be a command

Exec & - which closes the standard input stream (in this case, a file). A similar technique is used
mostly in scripts that run on logoff.

Exec command pointer to file with descriptor 0 (stdin). This pointer can be restored only after the script finishes.
If the script is supposed to continue reading data from the keyboard, then you need to save
a pointer to the old input stream. Below is a small script that demonstrates how to do this.

$ cat f_desc
#! / bin / bash
exec 3 & 0 0file
read linel
read line2
exec 0 & 3
echo $ 1inel
echo $ line2

The first exec command stores a pointer to standard input (stdin) in file descriptor 3
(any integer between 3 and 9 is allowed) and then opens file for reading. The next two read commands
reads two lines of text from the file. The second exec command restores the pointer to standard input: now
it is linked to file stdin, not file. The final echo commands display the contents of the lines read on the screen,
which were stored in the variables linel and Iine2.

The result of the script:
$ ./ f_desc
Hey!
Bye!

Did you like the article? To share with friends: