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> 0 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 0 | 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 un 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 un 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 0 (standard input). | |