Entry 000 – Redirection

Welcome to the first entry of Linux in the Shell.  Before delving into specific commands, redirection will be explored as redirection will be used frequently in the examples going forward.  The Unix philosophy posits program simplicity and that a program should do one thing and do it well (Mike Gancarz, the Unix Philosophy).  Eric Raymond adds the Rule of Composition:  ”Design programs to be connected to other programs.”  Redirection is the glue that achieves this design.

Redirection is applied to any of the following standard streams to achieve results beyond simply outputting some value from a single command:

  • Standard Input (stdin) – 0
  • Standard Output (stdout) – 1
  • Standard Error (stderr) – 2

The numbers: 0,1 and 2 are file descriptors – “abstract indicators for accessing a file.” Therefore, each of the standard streams are considered as acting like a file to the OS. That is, file directors can be applied to not only files but “directories, block or character devices, sockets, FIFO’s (named pipes), and unnamed pipes.”  Delving deeper in these constructs are beyond the entry of this post; suffice to say that the three streams can be treated in many different ways to achieve different outcomes through the use of redirection.  For more information on file descriptors or a deeper understanding of the standard streams consult the WikiPedia entries linked above.

The focus of this entry is the use of the following three symbols to facilitate redirection:

  • > or >>  - output redirection
  • < or <<  - input redirection
  • | – pipe

Output redirection is simply redirecting the output of a command from stdout to somewhere else.  More often than not redirection is to a file to be processed in another manner:

ls /home/dann/music > musiclist.txt

This examples redirects the output of the ls (list) command in the /home/dann/music directory to a file called musiclist.txt.  Instead of the output of the ls command being directed to the screen, the output is directed to the file. If the musiclist.txt file is read the contents would be the output of the ls command one would typically see directed to the screen.

A single “>” writes destructively.  That is, it will take the contents of stdout and replace whatever existed in the location it is being redirected to with stdout:

cat /dev/null > musiclist.txt

Because “>” is destructive, the contents of musiclist.txt have now been overwritten by the output of the cat (concatenate) command being redirected in to musiclist.txt.  (/dev/null, aka:  the bit bucket; is a special device file that provides no data.) Simarly:

ls /home/dann/music2 > musiclist.txt

will again redirect the output of the directory listing of music2 to the file musiclist.txt obliterating any data that was already in musiclist.txt with the output of the command.

If we wanted to preserve the contents of musiclist.txt and append the output of the ls command in the third example, then “>>” is used.  Instead of overwriting the output, the stream appends to when the stream is redirected.

ls /home/music2 >> musiclist.txt

“>” by itself redirects only stdout, it does nothing for stderr.  If you want to redirect stderr you must specify the file descriptor value of stderr along with “>”:

cat mememe 2> error.list

Supposing the file mememe does not exist, instead of showing the error:  ”cat mememe:  No such file or directory” that output of stderr is directed to the file error.list.  Recall that “>” is destructive so if we ran the comand again, it would replace the contents of error.list with the same message.  If we wanted to instead append errors to the error.list file:

cat mememe 2>> error.list

Take for instance this example:

cat file1 mememe 1> error.list

Notice that instead of “>”, “1>” was used.  Recall that the file descriptor for output is 1.  Essentially this command is identical to:  cat file1 mememe > error.list.  Now if “file1″ exists but “mememe” does not, the contents of file1 will be written to error.list and the error:  ”cat mememe:  No such file or directory” is written to the screen.  If we wanted to redirect both stdout and stderr to the file error.list the “&” is used:

cat file1 mememe &> error.list

Now nothing is written to the screen and both the output of “file1″ and the error from non-existent “mememe” are written to error.list.  But what if we wanted to write only errors to the file, if there are any?  Again, the file descriptor for stderr is used in conjunction with “>”:

cat file1 mememe 2> error.list

In this example the output of “file1″ is shown on the screen and the error message from “mememe” is redirected to error.list.

Take note that if you want to redirect both stdin and stderr to a file this can only be done destructively with “>”.  There is no “&>>” functionality.

 

Input redirection, “<” redirects a stream to the input of a command:

wc < musiclist.txt

In this example the file musiclist.txt is passed to the wc command.  This example is not very practical because it essentially produces the same output as wc musiclist.txt.

The use of “<<” does not mean append in the case of stdin.  Instead it can be used to represent a break point in the input.  That is, accept input until a token is received:

cat > poem.txt << “EOF”

This example is a quick and dirty text editor that only does input.  This will accept input from stdin (keyboard in this case) and write it to the file poem.txt until “EOF” is passed through stdin. At that point the cat will exit and close poem.txt.  This type of redirect is used a lot when building Linux From Scratch.

The final redirect we will cover is the “|” or pipe redirect.  ”|” is used primarily to pass the output of one command to the input of another:

ls |grep music

In this example the output of the ls command is passed to grep.  That ouput is checked to see if there is a file or directory with the word music in the listing.   Another more useful example is:

ls -lt |less

This example pass the output of ls to the less command allowing you to filter through the directory listing.

The “|” can be used with other redirection techniques to chain together a useful string of commands and produce some desired result:

grep -R “dann@thelinuxlink.net” * | grep -v svn |  \

cut -d”:” -f1  > whereIAmListed.txt

This examples greps recursively through the current directory structure looking for all instances of the email address “dann@thelinuxlink.net”, filters out anything that has svn in the result, pass the filtered list to cut setting a delimiter of “:” and outputting only the first field (everything before the first “:”) which is redirected to a file called whereIAmListed.txt.

Take note of the “\” after the second “|”.  This has no bearing on the command as a whole it is just a way to represent that this is a single string across multiple lines.  If you typed this in as shown, hitting the enter key after the “\” the string would process normally.  This syntax is merely to show that the above string is all one line even though format conventions of this media spread it out over two lines.

This entry covered redirection of standard streams:  input, output, and error.  The symbols utilized were “>”, “>>”, “<”, “<<”, and “|”.  It should be noted that redirection to and from a file makes use of the “<”and “>” symbols, whereas redirection of the output of one command to another makes use of the “|” symbol.  This is just the tip of the iceberg on redirection, but enough to give an understanding as we go forward with exploring commands in the Linux bash shell.  If you are interesting in exploring redirection more thoroughly consult these links:

 

 

If the video is not clear enough view it off the YouTube website and select size 2 or full screen.  Or download the video in Ogg Theora format:

Thank you very much!

 

This entry was posted in Uncategorized. Bookmark the permalink.

11 Responses to Entry 000 – Redirection

  1. Johnnyrberg says:

    Blessings ty I am greener then green and need the bare fundamentals. Looking forward to instruction.

  2. dannSWashko says:

    Sweet Johnnyberg! This show is for you! I will be covering a lot of fundamentals along with some more esoteric commands along the way!

  3. Twisted Lucidity says:

    Doesn’t “&>” redirect stdout and stderr, rather than stdin and stderr as stated above?
    And doesn’t “cat file1 mememe 1>> error.list 2>> error.list” accomplish the same as “&>>”?
    And…err…”&>>” does seem to exist. (http://www.gnu.org/software/bash/manual/bashref.html section 3.6.5) I tried it and it appeared to work (I think their “This is semantically equivalent to” example should be “>>word 2>>&1″)
    Or am I just being more thunderously dense than usual?

    • Twisted Lucidity says:

      I’m wrong on the “2>>&1″ thing, so I’m probably wrong about everything else.

    • dannSWashko says:

      Thanks for catching that. I read through this thing so many times and never noticed the error. You are correct in that &> redirection stdout and stderr, not stdin and stderr.

      Again Thanks!

    • dannSWashko says:

      Twisted Lucidity &>> does seem to exist on newer versions of bash. I tested this on a few systems with mixed results. On Arch it worked as expected but on CentOS 5.2 it did not. CentOS had bash version 3.2.25 and Arch 4.4.20(2). That is probably why. Documentation you linked to was for 4.1. I should probably incorporate this into the post or add another post for errata. I’ve not fully considered how I want to handle such things yet.

      Thanks!

      • Twisted Lucidity says:

        Heh – never actually occured to me that there would be versions of bash with different features, I thought it was stable and only errors got fixed (no idea where that notion came from…maybe a “CLI==Old” mentality?).

        I found another error (sorry):
        “>” by itself redirects only stdin, it does nothing for stderr.
        I think that should be stdout.

        Why not simply update the current post and have a small heading “Errata fixed on 1/2/12″ or something?

        I’m looking forward to following this show, my bash-fu is a bit weak.

  4. zbreaker says:

    Great….been looking forward to this cast. While I’m not a total noob I’m sure there will
    be a lot to absorb here.

  5. Pingback: Aprirsi nel guscio | Script | iCreate

  6. Mark Rice says:

    I am looking forward to the next ‘cast. While I am not afraid of the command line, there is always so much to learn.

  7. Wizno says:

    Great post and great blog. I’ve done a little bash scripting but never understood >, >>, <<, < etc when I saw examples.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>