File Redirection, Named and un-named pipes

In the Linux shell, each process has three file handles (also called file descriptors, or fd's for short) associated with it.

Figure 4.7. stdin, stdout, stderr

stdin, stdout, stderr

You can tell the Linux shell to change any or all of these on a per-command basis, by using pipes ("|") and redirections ("<" and ">").

These features are useful if you want, for example to get the output of a command into a file for later perusal, or if you want to string multiple commands together in order to achieve the desired result.

Remember, Linux is made up of lots of small building blocks that can be put together in order to make something more complicated; the pipes and redirections are what you can use to help join the blocks together.

stdin

The standard input is usually taken from what you type in at the keyboard. However we could take the output from a file.

We would use the less than sign (<) to redirect input.

 command 0&lt; filename or command &lt; filename 

stdout

If we want to store the output of a command in a file we would use standard output and redirect it. Normally by default the output goes to the screen. . If the file doesn't already exist, it will be created.

We use the greater than sign (>) to redirect standard output.

 command 1&#62; filename or command &#62; filename 

stderr

It is important to think of output from a command and errors produced by a command as separate actions. We might want to store the output of a command in a file and leave the errors to display on the screen. Or we might want to store the error messages in a file.

	command 2&#62; filename
            

In this instance the number "2" preceding the redirection sign is not optional.

        student@debian:~$ touch file1 file2
	
            

Make sure that file1 and file2 exist in your directory, file3 should not exist.

student@debian:~$ ls file1 file2
        file1 file2

Standard output goes to the screen and there are no error messages.

student@debian:~$ ls file1 file2 file 3
        file3 ls: file3: No such file or directory file1 file2

File3 does not exist so a message is printed to standard error. The directory listing for file1 and file2 is printed to standard output.

student@debian:~$ ls file1 file2
        file3 &#62; stdout.txt ls: file3: No such file or directory

Redirect standard output to a file called stdout.txt, standard error is kept as the default display to the screen.

student@debian:~$ ls file1 file2
        file3 2&#62; stderr.txt file1 file2

Redirect standard error to a file called stderr.txt, standard output is left to the default setting of the screen.

student@debian:~$ ls file1 file2
        file3 &#62; stdout.txt 2&#62; stderr.txt student@debian:~$ _

Redirect standard output and standard error and nothing is displayed on the screen.

student@debian:~$ cat stdout.txt
        file1 file2  student@debian:~$ cat stderr.txt ls:
        file3: No such file or directory

Check what is in each relevant file.

For standard input we can demonstrate how it works however at this stage of your course it is harder to describe a really useful example.

A simple example would be:

student@debian:~$ cat <
        stdout.txt file1 file2

When we know a little more we could do something more sophisticated, like run a program that normally requires input from a user at a keyboard - but run it after hours in the background with no user present to press the relevant key strokes.

Appending to a file

You can use a double redirection (">>") to append to a file instead of overwriting it. If the file doesn't already exist, it will be created.

student@debian:~$ ls output.txt 
ls: output.txt: No such file or directory      

Make sure that the file does not already exist in your home directory.

 student@debian:~$ echo &quot;test&quot; &#62;&#62; output.txt
 student@debian:~$ cat output.txt
 test 
 student@debian:~$ echo &quot;test again&quot; &#62;&#62; output.txt 
student@debian:~$ cat output.txt 
test test again      

The above two steps will prove that the append function actually does create the file if it does not already exist.

Piping

A pipe ("|") directs the stdout from one process to the stdin of another:

Figure 4.8. piping from one process to another

piping from one process to another

Note that stderr is _not_ passed through the pipe!

student@debian:~$ ls dataset2 | grep &quot;txt&quot; 
fight.txt
flight.txt
org.txt
singularity.txt
three.txt
vernor.txt
vinge.txt
student@debian:~$ _ 

This type of pipe is called an "un-named pipe". The un-named pipe uses a temporary buffer type of action to pass the stream of data through.

You can also use "named pipes". We briefly mentioned them earlier in this course; they are also known as FIFO buffers.

Named pipes work exactly the same as unnamed pipes, where the stdout from one process is fed into the stdin for another process.

You can use the mkfifo command to create such a file, and you can then simply use the redirection symbols to put data in, or take it out. As the name implies, the data is read First In, First Out.

student@debian:~$ mkfifo foop 
student@debian:~$ ls -l foop 
prw-r--r-- 1 mwest mwest 0 Jan 13 23:26 foop| 
student@debian:~$ echo &quot;testing the named pipe&quot; &#62; foop 

Ok, now go and open up another terminal. You can do this by holding down the Alt key and pressing F2. Once there, log in, and then type the following:

student@debian:~$ cat < foop 
testing the named pipe
student@debian:~$ _ 

If you switch back to your original terminal window (press alt-f1), you should see that your shell has now returned back to your prompt. This is because your previous "cat" command took the contents out of the pipe, and so your original "echo" command was able to complete.

Check if the file called "foop" still exists as a named pipe in your directory.

Experiment with this one a bit, it can be quite fun!