The Command Line

Running Programs

It's hard to get much accomplished without running a program; you might be able to prop something up with your computer or hold a door open, and some will make the most lovely humming noise when running, but that's really about it. And I think we can all agree that its use as a humming doorstop isn't what brought the personal computer the popularity it now enjoys.

So, remember how almost everything in Linux is a file? Well, that goes for programs, too. Every command you run (that isn't built into the shell) resides as a file somewhere. You run a program simply by specifying the full path to it.

For instance, remember that su command from the last section? Well, it's actually in the /bin directory: /bin/su would run it nicely.

So why, then, does just typing su work? After all, you didn't say it was in /bin. It could just as easily have been in /usr/local/share, right? How did it know? The answer to that lies in the PATH environment variable; most shells have either PATH or something very like PATH. It basically contains a list of directories to look in for programs you try to run. So when you ran su, your shell ran through its list of directories, checking each one for an executable file called su that it could run; the first one it came to, it ran. This happens whenever you run a program without specifying a full path to it; if you get a Command not found error, that only means that the program you tried to run isn't in your PATH. (Of course, this would be true if the program doesn't exist at all...) We'll discuss environment variables in more depth in the section called The Bourne Again Shell (bash).

Remember also that “.” is shorthand for “the directory I'm in”, so if you happened to be in /bin, ./su would have worked as an explicit full path.

Wildcard Matching

Nearly every shell recognizes some characters as being substitutes or abbreviations that mean “anything goes here”. Such characters are aptly named “wildcards”; the most common are * and ?. By convention, ? usually matches any single character. For instance, suppose you're in a directory with three files: ex1.txt, ex2.txt, and ex3.txt. You want to copy all of those files (using the cp command we cover in the section called cp in Chapter 10) to another directory, say /tmp. Well, typing cp ex1.txt ex2.txt ex3.txt /tmp is entirely too much work. It's much easier to type cp ex?.txt /tmp; the ? will match each of the characters “1”, “2”, and “3”, and each in turn will be substituted in.

What's that you say? That's still too much work? You're right. It's appalling; we have labor laws to protect us from that sort of thing. Fortunately, we also have *. As was already mentioned, * matches “any number of characters”, including 0. So if those three files were the only ones in the directory, we could have simply said cp * /tmp and gotten them all in one fell swoop. Suppose, though, that there is also a file called example.txt and one called hejaz.txt. We want to copy example.txt but not hejaz.txt; cp example* /tmp will do that for us.

cp example?.txt /tmp, would, of course, only get our original three files; there's no character in example.txt to match that ?, so it would be left out.

Input/Output Redirection and Piping

(Here comes something cool.)

   $ ps > blargh

Y'know what that is? That's me running ps to see which processes are running; ps is covered in Chapter 11 That's not the cool part. The cool part is > blargh, which means, roughly, “take the output from ps and write it to a file called blargh”. But wait, it gets cooler.

   $ ps | less

That one takes the output from ps and “pipes” it through less, so I can scroll through it at my leisure.

   $ ps > > blargh

This is the third most commonly used redirector; it does the same thing as “>”, except that “> >” will append output from ps to the file blargh, if said file exists. If not, just like “>”, it will be created. (“>” will obliterate the current contents of blargh.)

There is also a “<” operator, which means “take your input from the following”, but it's not used nearly so often.

   $ fromdos < dosfile.txt > unixfile.txt

Redirection gets really fun when you start piling it up:

   $ ps | tac > > blargh

That will run ps, reverse the lines of its output, and append those to the file blargh. You can stack as many of these up as you want; just be careful to remember that they get interpreted from left to right.

See the bash(1) man page for more detailed information on redirection.