![]() |
| |||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The concept of standard in and standard out streams makes possible the construction of a chain of Unix commands. Each command takes the output of its previous command. This technique is called piping. Pipelines are set up by the shell, which arranges for the standard input of command #n to be read from the standard output of command #(n-1). Here is an example. % ls -al | grep "^........w"This command pipes the output of a long listing such as % ls -al-rw-r--r-- 1 saruman staff 18 Nov 13 16:57 eg -rw-r--r-- 1 saruman staff 0 Dec 12 17:28 err -rw-r--r-- 1 saruman staff 96 Nov 24 16:55 f1.txt -rw-r--r-- 1 saruman staff 70 Nov 24 16:56 f2.txt -rw-r--r-- 1 saruman staff 98 Nov 24 17:06 f3.txt -rw-r--r-- 1 saruman staff 52 Nov 13 19:48 hw -rwxrwxrwx 1 saruman staff 181 Nov 11 15:02 letter.txt -rw-r--r-- 1 saruman staff 181 Dec 12 17:35 letter.txt.2 -rw-r--r-- 1 saruman staff 170 Nov 12 15:01 list into 'grep'. 'grep' then searches for files that have write access granted to 'others'. (I.e. 'grep' searches for lines that have a 'w' as the 9th character from the start.) The two commands together give the following output. % ls -al | grep "^........w"-rwxrwxrwx 1 saruman staff 181 Nov 11 15:02 letter.txt Without pipelines, one would have to use an intermediate file as in: % ls -al > tmp.txt% grep "^........w" tmp.txt % rm tmp.txt Another commonly used technique is to pipe the output of 'ps' into 'grep' to print the details of a particular process. The 'ps' command alone displays the details of all running processes on the Terminal window. For example: % ps cxPID TT STAT TIME COMMAND 190 ?? Ss 52:35.75 ATSServer 303 ?? Ss 525:37.45 Window Manager 399 ?? Ss 6:58.36 loginwindow 435 ?? Ss 0:01.24 pbs 445 ?? S 12:47.86 Dock 448 ?? S 43:53.17 UniversalAccess 449 ?? S 134:40.70 SystemUIServer 450 ?? S 22:44.58 Finder 452 ?? S 15:04.27 LaunchBar 453 ?? S 0:43.14 LiteSwitch X ...... If I were interested in just OmniWeb I could use: % ps cx | grep -i omniweb27423 ?? S 0:04.64 OmniWeb 'grep' is filtering the output of 'ps' and passing only lines that contain 'omniweb' to its standard out. |
Tell Me More...
|
|
'ps' 'ps' is a useful command that prints the status of commands running on your Mac. It is useful to check whether a system daemon in running, or to find out the process ID of an errant command you wish to 'kill'. Useful options are: x - list commands that does not have a controlling Terminal (most) a - list all commands (not just owned by the current user) u - list extra details (rather like '-l' does for 'ls') c - print only the command name, not the whole pathname ww - do not truncate output lines. If lines are truncated then the information you are after may be in the truncated portion. As usual: % man pswill put you in the know. 'sudo' and piplines When sudo is used to execute a pipeline: sudo cmd1 | cmd2the shell will interpret this as: (sudo cmd1)pipelined to cmd2Hence cmd1 is run as root, but cmd2 is not. |
A Neat 'grep' Trick
The option 'u' tells 'ps' to include more information about each process.
% ps cux | grep -i omniwebThe problem with this is that the heading normally printed at the top of the process list has been filtered out. It is possible to get this back by giving 'grep' two patterns to match.
For example:
% ps cux | grep -i -e omniweb -e pidOr:
% ps cxu | grep -i -E "(omniweb|pid)"|
When the output from a command scrolls off the screen, pipe it to 'less'. % ls -al / | less'less' is covered in Tutorial 2. % find . | less'find' is covered in Tutorial 5. Long Pipelines A pipeline can connect more than two commands. A four stage pipeline would look like: % cmd1 | cmd2 | cmd3 | cmd4Output is passed from command to command, each filtering or changing the output of the previous command before passing it onto the next command in the pipeline. |
Tell Me More...
|
|
Pipe Standard Error A pipeline pipes standard out, but not standard error. For example: % cat zxzxz | grep Hellocat: zxzxz: No such file or directory The error message was not passed to 'grep' To pipe standard error too use: % cat zxzxz |& grep Hello% 'grep' has filtered the error message. |
A Challenge
The "Tell Me More..." sidebar showed how to redirect standard out and standard error:
% cat zxzxz >& outTo redirect them to different files use the following trick:
% ( cat letter.txt > out ) >& errHow could one redirect standard error but not standard out?
Next Part
In Part 8 I will introduce shell scripts. A shell script is a small program written in the shell's scripting language that can perform quite complex tasks. The script is usually written to a file and can be executed like any other command.
Until then, observe the differing output from these two commands.
% (cd /; pwd); pwdI will explain what is happening at the start of Part 8.
Enjoy :-)
Discuss this article in the Learning Center forum
|
|
Part 7 - Redirection and Pipelines (page 2 of 2) |
|
| Copyright © 2000-2010 Inside Mac Media, Inc. All rights reserved. | ||
| Apple assumes no responsibility with regard to the selection, performance, or use of the products or services. All understandings, agreements, or warranties, if any, take place directly between the vendors and prospective users. | ||
| Apple, the Apple logo, Mac, PowerMac G4, PowerMac G5, Xserve, Xserve RAID, PowerBook, iBook, Airport, AirPort Extreme, iMac, eMac, iLife, iMovie, iCal, iPhoto, iTunes, QuickTime, FireWire, iPod, iSight, AppleWorks, Macintosh, Jaguar, Panther, Mac OS, Mac OS X and Mac OS X Server are trademarks of Apple Computer, Inc. |