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.
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.
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
, 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.
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:
catfile1
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 %
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:
catfile2
>>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
.
3.133.151.181