Dumb question on (Unix) pipe

I'm a Unix newbie - you can tell this as I'm still experimenting with 'cd' and 'ls'. I don't seem to be able to 'pipe' commands.


I type 'cd Documents | ls' whihc I think should open the Documents directory and list the files but all I get is the list of files at the root. If I enter the two commands seperately it works.


I'm assuming it is something to do with 'pipe' which I'm getting from a MacBook Pro UK keybaord by typing 'shift-\'.


I'm doing something dumb but what?


Thanks.

MacBook Pro 2.66GHz i7, Mac OS X (10.6.6)

Posted on Feb 10, 2012 6:42 AM

Reply
8 replies

Feb 10, 2012 7:28 AM in response to Mark Wooding

Welcome to the wonderful and weird world of the Unix command line. Before going any farther I'd strongly advise a trip to the book store of your choice to pick up one of the many good Unix references. You'll need it. Also become very familiar with the man (manual) command. Everything you what to know is in there somewhere.


Ok for this question there are two points you need to be aware of. One the pipe (|) symbol is used to transfer the output of one command to the input of the next command. So in your case you're trying to take the output of cd and pipe it into ls.


Why doesn;t this do anything? Well for one cd doesn't produce any output. It only changes the current working directory and second ls doesn't take in any input it reads the directory of either the cwd (current working directory) or else the directory passed into as a command line argument.


But this wouldn't work even if cd outputted anything and ls inputed anything. Why? Try this cd Documents | pwd (pwd is the command print working directory, tells you where you are in the filesysystem).


Notice that after you change to Documents the pwd still shows the directory you started from. The reason is that each command in a pipe chain is executed in a subshell. A new instance of the shell is created to run each command, when the command is finished the subshell exits. What a subshell does (usually) will not affect the shell that called it


Hoepfully this was some help. Good luck


regards

Feb 10, 2012 7:43 AM in response to Mark Wooding

A pipe sends the output of the first command to the next command. The isn't any output from the command cd.


The following example uses a pipe that will list the files/directories in the current working directory (ls is the first command) then pipe the results (standard out) to the while loop (the second command) and prints one file/directory per line.


ls | while read line
do
echo $line
done

Feb 10, 2012 8:00 AM in response to Mark Wooding

In the example you are using you would want semi-colon


cd Documents; ls


Or just


cd Documents
ls


A very common usage of pipe would be filter the output from the ls command


ls | grep -i "pdf"


which will give you a list of all the filenames that contain "pdf' in their name. If you just want the files that end in "pdf" it would be


ls | grep -i "pdf$"


Of course you could do the same thing using a wildcard and the ls command alone


ls *.pdf


but filtering the output of another command can be much more complex than what a simple wildcard can generate, and not all commands will allow you to select exactly what they display.


You can do more than filter via a pipe, for example


ls *.pdf | while read variable
do
    mv "$variable" "My.$variable"
done


which would rename every pdf file so it starts with "My.". Again more complicated operations can be crafted by combining several commands into a single pipeline. For example


cat tmp.txt | tr 'A-Z' 'a-z' | tr -cs 'a-z' '\n' | sort | uniq | comm -23 - /usr/share/dict/words


which will list all the tmp.txt words that do not exist in /usr/share/dict/words (this is a clasic pipeline created back in the early days of Unix).


Pipelines for fun an profit.


As Frank as suggested, spend some time looking at one of the Unix shell books at your local bookstore. The shell (in this case 'bash') basics are pretty much the same for all flavors of Unix/Linux

Feb 10, 2012 10:32 AM in response to Mark Wooding

To follow up...


Each process has three standard streams it uses: standard input, standard output, and standard error. They are usually appreviated with stdin, stdout, and stderr - sometimes in caps.


A pipe is a one-way connection of an output stream with some other input stream. It doesn't (easily) go both ways. It also doesn't (easily) handle both standard output and standard error. Some programs will send output to both standard output and standard error, which can be a pain.


When you are running a shell, your keyboard is the standard intput and both standard output and standard error are displayed in the terminal. However, any open file handle or network stream can be redirected to or from some processes standard I/O.

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Dumb question on (Unix) pipe

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.