Input/Output Redirection
The Korn shell provides a number of operators than can be used to manipulate command input/output and files. For example, you can save command output to a file. Or instead of typing in the input to a command, it can be taken from a file. The following sections describe some of the features of Korn shell I/O redirection.
Redirecting Standard Output
The standard output of a command is by default directed to your terminal. By using the
>
symbol, the standard output of a command can be redirected to a file, instead of your terminal. In this example, the standard output of the
echo
command is put into the file
p.out
:
$ echo "Hello" > p.out
$ cat p.out
Hello
If the file doesn't exist, then it is created.
Otherwise
, the contents are usually overwritten, usually, but not always. If you have the
noclobber
option set (discussed in the
next
section), or the file attributes (permissions and/or ownership) do not permit writing, the file will not be overwritten. If we change permission on
p.out
and try to direct output to it again, we get an error message:
$ chmod 444 p.out
$ echo "Hello again" > pwd.out
/bin/ksh: p.out: cannot create
We'll see in the next section how to force overwriting of existing files using a variation of the > redirect operator.
You can also use the
>
command to create an empty file:
$ > tmp
$ ls s tmp
0 tmp
This is equivalent to
touch tmp
.
Standard output can be appended to a file by using the
>>
redirect operator. Here, the output of
find
is appended to
deadfiles.out
:
$ echo "Dead File List" > junk.out
$ find . name dead.letter print >>junk.out
$ find . name core print >>junk.out
$ cat junk.out
Dead File List
./mail/dead.letter
./bin/core
Standard output is closed with the
>&?/span> redirect operator:
$ echo "This is going nowhere" >&?/span>
$
This feature can be used in a Korn shell script to close the output of a
group
of commands instead of redirecting the output of each command individually.
The
noclobber
Option
To prevent redirecting output to an existing file, set the
noclobber
option. By default, this feature is usually disabled, but can be enabled with the
set -o noclobber
command:
$ ls > file.out
$ set o noclobber
Now when we try to redirect output to
file.out
, an error message is returned:
$ ls > file.out
/bin/ksh: file.out: file already exists
The
>
operator is used to force overwriting of a file, even if the
noclobber
option is enabled. Here,
file.out
can now be overwritten, even though the
noclobber
option is set:
$ ls > file.out
Redirecting Standard Input
Standard input to a command is redirected from a file using the
<
operator. This feature can be used to read in a mail message from a file, instead of typing it in:
$ mail dick jane spot < mlist
This could also be implemented using a pipe:
$ cat mlist mail dick jane spot
In both cases, file
mlist
becomes the standard input to
mail
.
Table 2.2. Some I/O Redirection Operators
|
<
file
|
redirect standard input from
file.
|
|
>
file
|
redirect standard output to
file
. Create
file
if non-existent, else overwrite.
|
|
>>
file
|
append standard output to
file
. Create
file
if non-existent.
|
|
>
file
|
redirect standard output to
file
. Create
file
if non-existent, else overwrite even if
noclobber
is enabled.
|
|
<>
file
|
open
file
for reading and writing as standard input.
|
|
<&
?/span>
|
close standard input.
|
|
>&
?/span>
|
close standard output.
|
Standard input can be closed with the
<&?/span> redirect operator. Here, the standard input to the
wc
command is closed:
$ cat mlist wc l <&?/span>
Not really exciting. This is useful when manipulating file descriptors with the
exec
command, which is discussed later in Chapter 8.
File Descriptors
File descriptors are used by processes to identify their open files. The Korn shell automatically
assigns
file descriptor 0 to standard input for reading, file descriptor 1 to standard output for writing, and file descriptor 2 to standard error for reading and writing. The file descriptors 3 through 9 can be used with I/O redirection operators and are opened, closed, and/or
copied
with the
exec
command, which is discussed later in Chapter 8.
Redirecting Standard Error
Most Unix commands write their error messages to standard error. As with standard output, standard error is by default directed to your terminal, but it can be redirected using the standard error file descriptor (2) and the
>
operator. For example, the
ls
command displays a message on standard error when you attempt to display information about a non-existent file:
$ ls tmp
tmp not found
Now, if you do an
ls
on an existent and non-existent file on the same command-line, a message about the non-existent file goes to standard error, while the output for the existent file goes to standard output:
$ ls tmp t.out
tmp not found
t.out
By using the
2>
operator, the standard error of the same command is redirected to
ls.out
. The standard output is still displayed directly to your terminal:
$ ls tmp t.out 2>ls.out
t.out
$ cat ls.out
tmp not found
There can be no space between the
2
and
>
symbol, otherwise the
2
is interpreted as an argument to the command.
Table 2.3. File Descriptors
|
|
standard input
|
|
1
|
standard output
|
|
2
|
standard error
|
|
3?
|
unassigned
file descriptors
|
More with File Descriptors
The
>&
n
operator causes output to be redirected to file descriptor
n
. This is used when you want to direct output to a specific file descriptor. To send the output of the
echo
command to standard error, just add
>&2
to the command-line:
$ echo This is going to standard error >&2
This is going to standard error
In the next command, the standard error and output are sent to
ls.out
by specifying multiple redirections on the same command line. First,
>&2
causes standard output to be redirected to standard error. Then,
2>ls.out
causes standard error (which is now standard output and standard error) to be sent to
ls.out
:
$ ls tmp t.out 2>ls.out 1>&2
$ cat ls.out
tmp not found
t.out
This command causes output to be redirected to both standard output and standard error:
$ { echo "This is going to stdout" >&1 ; \
echo "This is going to stderr" >&2 ; }
This is going to stdout
This is going to stderr
If the output of the last command was redirected to a file using the
>
operator, then only the standard output would be redirected. The standard error would still be displayed on your terminal.
$ { echo "This is going to stdout" >&1 ; \
echo "This is going to stderr" >&2 ; } >out
This is going to stderr
$ cat out
This is going to stdout
The
n
>&
m
operator causes the output from file descriptors
n
and
m
to be merged. This operator could be used in the previous command to direct both the standard output and standard error to the same file.
$ { echo "This is going to stdout" >&1 ; \
echo "This is going to stderr" >&2 ; } >out 2>&1
$ cat out
This is going to stdout
This is going to stderr
If you wanted the standard output and standard error appended to the output file, the
>>
operator could be used:
$ { echo "This is going to stdout again" >&1 ; \
echo "This is going to stderr again" >&2 ; } \
>>out 2>&1
$ cat out
This is going to stdout
This is going to stderr
This is going to stdout again
This is going to stderr again
As seen in the previous example, multiple file descriptor redirections can also be specified. To close the standard output and standard error of this
ls
command:
$ ls tmp t.out >&?2>&?/span>
$
The
print
and
read
commands have special options that allow you to redirect standard output and input with file descriptors. This is discussed in Chapter 8.
Here Documents
Here documents is a
term
used for redirecting multiple lines of standard input to a command. In looser terms, they allow batch input to be given to programs and are frequently used to execute interactive commands from within Korn shell scripts. The format for a here document is:
command
<<
word
or
command
<<?/span>
word
where lines that follow are used as standard input to
command
until
word
is read. In the following example, standard input for the
cat
command is read until the word
END
is
encountered
:
$ cat >> .profile <<END
> export TERM=sun-cmd
> export ORACLE_HOME=/apps/oracle
> END
The other variation,
command <<?word
, deletes leading tab
characters
from the here document. It is often used over the first variation to produce more readable code when used within larger scripts. A good use for here documents is to automate
ftp
file transfers. This snippet of code could be used within a larger script to automatically
ftp
code to or from another server.
$ ftp <<- END
open aspsun
user anonymous
cd /usr/pub
binary
get ksh.tar.Z
quit
END
Here Documents and File Descriptors
Here documents can also be used with file descriptors. Instead of reading multiple lines from standard input, multiple lines are read from file descriptor
n
until
word
is read.
command n
<<
word
or
command n
<<?/span>
word
Discarding Standard Output
The
/dev/null
file is like the system trash bin. Anything redirected to it is discarded by the system.
$ ls >/dev/null
This is not the same as:
$ ls >&?/span>
which
closes
standard output.
Table 2.4. Redirect Operators and File Descriptors
|
<&
n
|
redirect standard input from file descriptor
n.
|
|
>&
n
|
redirect standard output to file descriptor
n.
|
|
n
<
file
|
redirect file descriptor
n
from
file.
|
|
n
>
file
|
redirect file descriptor
n
to
file.
|
|
n
>>
file
|
redirect file descriptor
n
to
file
. Create
file
if non-existent, else overwrite.
|
|
n
>
file
|
redirect file descriptor
n
to
file
. Create
file
even if
noclobber
is enabled.
|
|
n
<&
m
|
redirect file descriptor
n
input from file descriptor
m
.
|
|
n
>&
m
|
redirect file descriptor
n
output to file descriptor
m
.
|
|
n
<>
file
|
open
file
for reading and writing as file descriptor
n
.
|
|
n
<<
word
|
redirect to file descriptor
n
until
word
is read.
|
|
n
<<
?/span>
word
|
redirect to file descriptor
n
until
word
is read; ignore leading tabs.
|
|
n
<&
?/span>
|
close file descriptor
n
for standard input.
|
|
n
>&
?/span>
|
close file descriptor
n
for standard output.
|
|
print -u
n args
|
redirect arguments to file descriptor
n
. If
n
is greater than
2
, it must first be opened with
exec
. If
n
is not specified, the default file descriptor argument is
1
(standard output).
|
|
read -u
n args
|
read input line from file descriptor
n
. If
n
is greater than
2
, it must first be opened with
exec
. If
n
is not specified, the default file descriptor argument is
(standard input).
|
|