Wednesday, July 27, 2011

Data redirection commands in *NIX

Data redirection with >, >>, <, and <<

Another important aspect of executing commands from the command-line interface (CLI) is the ability to write various outputs to a device or to read input into a command from another device. To write the output of a command, append the greater-than symbol (> or >>) and the target file name or device desired after the command to be executed. If the target file doesn't exist and you have Write permissions to the target directory, > and >> create the file with permissions of your umask and write the command's output to the newly created file. If, however, the file does exist, > attempts to open the file and overwrite the entire contents. If you would rather append to the file, simply use >>. Think of it as the flow of output data moving from the command on the left moving to the destination file on the right (that is, <cmd> -> <output> -> <file>).
The following example executes the ps –ef and redirects the output to a file namedps_out:
# ps –ef | grep –E "rpc|ksh" > ps_out
Data redirection with >, >>, <, and <<

The following code executes the earlier extended pipeline example and redirects the output to the same file—ps_out—but appends to the current data:
# ps –ef | grep –E "rpc|ksh" | grep -vE "grep|rpc.ttdbserver" | 
   awk -v _MAX_PID=200000 '{if ($2 > _MAX_PID) {print "PID for 
   process",$8,"is greater than", _MAX_PID}}' >> ps_out

Listing 3 shows the output from the last two redirections.

Listing 3. Output from subsequent redirections

# cat ps_out

    root  196718  151674   0 11:00:27      -  0:00 /usr/sbin/rpc.mountd
  daemon  225402  151674   0 11:00:27      -  0:00 /usr/sbin/rpc.statd
    root  229498  151674   0 11:00:27      -  0:00 /usr/sbin/rpc.lockd
    root  340144  168018   0 12:34:56      -  0:00 rpc.ttdbserver 100083 1
 cormany  409708  569522   0 19:29:27  pts/1  0:00 -ksh
 cormany  733202  409708   0 19:52:20  pts/1  0:00 grep -E rpc|ksh
PID for process /usr/sbin/rpc.statd is greater than 200000
PID for process /usr/sbin/rpc.lockd is greater than 200000
PID for process -ksh is greater than 200000

When redirecting output with > alone, only the stdout of the command is redirected. Keep in mind that with computing, there is stdout as well as stderr: The former is represented as 1, while stderr is 2. Redirecting output in UNIX is no different. Simply place the desired output type before the > (for example, 1>2>) to tell the shell where to route the output.
Listing 4 attempts to list files fileA.tar.bz2 and fileC.tar.bz2. Unfortunately, as shown in the first command (ls), fileC.tar.bz2 doesn't exist. Thankfully, we remembered to separate stdout into ls.out and stderr into ls.err.

Listing 4. Listing the files fileA.tar.bz2 and fileC.tar.bz2

# ls
fileA.tar.bz2   fileAA.tar.bz2  fileB.tar.bz2   fileBB.tar.bz2

# ls fileA.tar.bz2 fileC.tar.bz2 1> ls.out 2> ls.err

# cat ls.out

# cat ls.err
ls: 0653-341 The file fileC.tar.bz2 does not exist.

The same rules apply in AIX with > and >> on stdout and stderr. For example, the same output files can be used for future tests, as Listing 5 shows.

Listing 5. Using output files for future tests

# ls fileB.tar.bz2 fileD.tar.bz2 1>> ls.out 2>> ls.err

# cat ls.out

# cat ls.err
ls: 0653-341 The file fileC.tar.bz2 does not exist.
ls: 0653-341 The file fileD.tar.bz2 does not exist.

There are times when you may need to have both stdout and stderr written to the same file or device. You can do this in either of two ways. The first method is to direct 1> and 2> to the same file:
# ls fileA.tar.bz2 fileC.tar.bz2 1> ls.out 2> ls.out

# cat ls.out
ls: 0653-341 The file fileC.tar.bz2 does not exist.

The second method is a simpler and quicker way to accomplish the same thing and is used more frequently by experienced UNIX users:
# ls fileA.tar.bz2 fileC.tar.bz2 > ls.out 2>&1

# cat ls.out
ls: 0653-341 The file fileC.tar.bz2 does not exist.

Let's break the statement down. First, ls fileA.tar.bz2 fileC.tar.bz2 is executed. The stdout is redirected to ls.out with > ls.out, and stderr is redirected to the same file to which stdout is redirected (ls.out) with 2>&1.
Remember that you can redirect output to files as well as other devices. You can redirect data to printers, floppy disks, Terminal Types (TTYs), and various other devices. For example, if you wanted to send a message to a single user on all sessions (or TTYs), you could just loop through who and redirect a message to the TTYs if you have adequate permissions, as shown inListing 6.

Listing 6. Redirecting a message to a TTY

# for _TTY in 'who | grep "cormany" | awk '{print $2}''
> do
>   _TTY="/dev/${_TTY}"
>   echo "Sending message to cormany on ${_TTY}"
>   echo "Test Message to cormany@${_TTY}" > ${_TTY}
> done

Sending message to cormany on /dev/pts/13
Test Message to cormany@/dev/pts/13
Sending message to cormany on /dev/pts/14

No comments:

Post a Comment