Chapter 6. Redirecting I/O

Many Unix programs read input (such as a file) and write output. In this chapter, we discuss Unix programs that handle their input and output in a standard way. This lets them work with each other.

This chapter generally doesn’t apply to full-screen programs, such as the vi editor, that take control of your whole Terminal window. (The pager programs, less, and more do work together in this way.) It also doesn’t apply to graphical programs, such as the Finder or Internet Explorer, that open their own windows on your screen.

Standard Input and Standard Output

What happens if you don’t give a filename argument on a command line? Most programs will take their input from your keyboard instead (after you press Return to start the program running, that is). Your Terminal keyboard is the program’s standard input .

As a program runs, the results are usually displayed on your Terminal screen. The Terminal screen is the program’s standard output . So, by default, each of these programs takes its information from the standard input and sends the results to the standard output. These two default cases of input/output (I/O) can be varied. This is called I/O redirection .

If a program doesn’t normally read from files, but reads from its standard input, you can give a filename by using the < (less-than symbol) operator. tr (character translator) is such a program. Here’s how to use the input redirection operator to convert commas to linefeeds in the to_do file:

% cat to_do
Install Mac OS X,Learn Unix,???,Profit!
% tr ',' '
' < to_do
Install Mac OS X
Learn Unix
???
Profit!
%

If a program writes to its standard output, which is normally the screen, you can make it write to a file instead by using the greater-than symbol (> ) operator. The pipe operator (| ) sends the standard output of one program to the standard input of another program. Input/output redirection is one of the most powerful and flexible Unix features.

Putting Text in a File

Instead of always letting a program’s output come to the screen, you can redirect output to a file. This is useful when you’d like to save program output, or when you put files together to make a bigger file.

cat

cat , which is short for “concatenate,” reads files and outputs their contents one after another, without stopping.

To display files on the standard output (your screen), use:

cat file(s)

For example, let’s display the contents of the file /etc/csh.login. This system file is the global login file for tcsh and csh.

% cat /etc/csh.login
# System-wide .login file for csh(1).

setenv PATH "/bin:/sbin:/usr/bin:/usr/sbin"
%

You cannot go back to view the previous screens, as you can when you use a pager program such as less (unless you’re using a Terminal window with a sufficient scrollback buffer, that is). cat is mainly used with redirection, as we’ll see in a moment.

By the way, if you enter cat without a filename, it tries to read from the keyboard (as we mention earlier). You can get out by pressing Control-D.

When you add > filename to the end of a command line, the program’s output is diverted from the standard output to the named file. The > symbol is called the output redirection operator.

Warning

When you use the > operator, be careful not to accidentally overwrite a file’s contents. Your system may let you redirect output to an existing file. If so, the old file will be deleted (or, in Unix lingo, “clobbered”). Be careful not to overwrite a much needed file!

Many shells can protect you from this risk. In the tcsh shell (the default shell for Mac OS X), use the command set noclobber . Enter the command at a shell prompt or put it in your .tcshrc file. After that, the shell won’t allow you to redirect onto an existing file and overwrite its contents.

This doesn’t protect against overwriting by Unix programs such as cp; it works only with the > redirection operator. For more protection, you can set Unix file access permissions.

For example, let’s use cat with the output redirection operator. The file contents that you’d normally see on the screen (from the standard output) are diverted into another file, which we’ll then read using cat (without any redirection!):

% cat /etc/csh.login > mylogin
% cat mylogin 
# System-wide .login file for csh(1).

setenv PATH "/bin:/sbin:/usr/bin:/usr/sbin"
%

An earlier example showed how cat /etc/csh.login displays the file /etc/csh.login on the screen. The example here adds the > operator, so the output of cat goes to a file called mylogin in the working directory. Displaying the file mylogin shows that its contents are the same as the file /etc/csh.login (the effect is the same as the copy command cp /etc/csh.login mylogin).

You can use the > redirection operator with any program that sends text to its standard output — not just with cat. For example:

% who > users
% date > today
% ls
mylogin   today   users   ...

We’ve sent the output of who to a file called users and the output of date to the file named today. Listing the directory shows the two new files. Let’s look at the output from the who and date programs by reading these two files with cat:

% cat users
taylor   console  Nov 11 22:06 
taylor   ttyp1    Nov 15 08:16 
% cat today
Fri Nov 15 17:11:00 EST 2002
%

You can also use the cat program and the > operator to make a small text file. We told you earlier to type Control-D if you accidentally enter cat without a filename. This is because the cat program alone takes whatever you type on the keyboard as input. Thus, the command:

cat > filename

takes input from the keyboard and redirects it to a file. Try the following example:

% cat > to_do
                  Finish report by noon
                  Lunch with Xian
                  Swim at 5:30
                  ^D
%

cat takes the text that you typed as input (in this example, the three lines that begin with Finish, Lunch, and Swim), and the > operator redirects it to a file called to_do. Type Control-D once, on a new line by itself, to signal the end of the text. You should get a shell prompt.

You can also create a bigger file from smaller files with the cat command and the > operator. The form:

cat file1 
                  file2 > newfile

creates a file newfile, consisting of file1 followed by file2.

% cat today to_do > diary
% cat diary
Fri Nov 15 17:11:00 EST 2002
Finish report by noon
Lunch with Xian
Swim at 5:30
%

Warning

You shouldn’t use redirection to add a file to itself, along with other files. For example, you might hope that the following command would merge today’s to-do list with tomorrow’s. This won’t work!

% cat to_do to_do.tomorrow > to_do.tomorrow

It works, but it runs for all eternity because it keeps copying the file over itself. If you cancel it with Control-C and use ls to examine the file, you’ll see that it’s gotten quite large:

                     ^C
% ls -sk to_do.tomorrow 
 81704 to_do.tomorrow

ls -sk shows the size in kilobytes, so it grew to about 80 megabytes! The right way to do this is by using a temporary file (as you’ll see in a later example) or simply by using a text editor program.

You can add more text to the end of an existing file, instead of replacing its contents, by using the >> (append redirection) operator. Use it as you would the > (output redirection) operator. So:

cat file2 >> file1

appends the contents of file2 to the end of file1. For an example, let’s append the contents of the file users and the current date and time to the file diary. Here’s what it looks like:

% cat users >> diary
% date >> diary
% cat diary
Fri Nov 15 17:11:00 EST 2002
Finish report by noon
Lunch with Xian
Swim at 5:30
taylor   console  Nov 11 22:06 
taylor   ttyp1    Nov 15 08:16 
Fri Nov 15 17:53:24 EST 2002
%

Unix doesn’t have a redirection operator that adds text to the beginning of a file. You can do this by storing the new text in a temporary file, then by using a text editor program to read the temporary file into the start of the file you want to edit. You also can do the job with a temporary file and redirection. Maybe you’d like each day’s entry to go at the beginning of your diary file. Simply rename diary to something like temp. Make a new diary file with today’s entries, then append temp (with its old contents) to the new diary. For example:[6]

% mv diary temp
% date > diary
% cat users >> diary
% cat temp >> diary
% rm temp


[6] This example could be shortened by combining the two cat commands into one, giving both filenames as arguments to a single cat command. That wouldn’t work, though, if you were making a real diary with a command other than cat users.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.151.181