In time you will become more aware of frequently used
combinations of commands. You might want to issue all commands in one line
and then direct your attention elsewhere. No problem. The shell lets you
put various special queuing characters between commands. This section introduces
the two most important of them.
Notice that I will use white spaces around these characters for clarities'
sake. You don't need them in real life, there's no difference between 'ls
-a ; du -hs' and 'ls -a;du -hs'.
command1 ; command2
executes command1 first and then command2,
even ifcommand1 returned an error.
Example:
ls -a ; du -hs
will first print a complete directory listing to the screen and then the
total amount of space the files in this directory and its subdirectories
take up.
command1 && command2
runs command2 if and only if command1
completed without an error.
Example:
$ ls -a bogusdir && du -hs
will return ls: bogusdir: No such file or directory and 'du'
won't be executed at all (presuming you don't have a directory called 'bogusdir',
that is ;-)). If you'd have used ';' instead, the 'du' would have been executed.
The classical example to demonstrate the difference
between ';' and '&&', and the usefulness of command queuing in general,
is the compilation and installation of the Linux kernel.
To compile and install the Linux, you need to execute a set of commands one
after the other: 'make dep', 'make clean', 'make bzImage', 'make modules',
'make modules_install' and 'make install'. It would be annoying to issue
one command, wait till it has completed, then run the next, wait, the next,
wait and so on. On the other hand every command in this row will only work
correctly if all the previous commands completed with no errors. If you use
';' to queue these commands and one of the commands fails, the rest will
be executed regardless, and you might end up with an faulty kernel image
in the '/boot' directory. So use '&&':
make dep && make clean && make
bzImage && make modules && make modules_install &&
make install
This will compile the kernel and its modules, install
them, without requiring any form of interaction.
section index top
When you run a command or start a program from a terminal,
that terminal is blocked as long as the command or program is running. In
Unix, we say that command or program is running in the 'foreground'. If you
need a terminal to run another command, you have to open a new one.
But there's a more elegant way, called 'jobbing' or
'backgrounding'. When you 'job' or 'background' a command, it will release
the terminal immediately, so that terminal can be used for new input right
away. To do this, all you have to do is to put an & behind the command:
gqview &
tells the shell to execute the graphical viewer 'GQview'
in the 'background' (i.e. to run it as a 'job').
The jobs command tells you which commands and programs are running
as jobs on this terminal window:
jobs
[1]+ Running gqview &
This is important when you consider to close a terminal
window, because upon closing the terminal all jobs running on it are terminated,
that is if I would close this terminal, the GQview program started from it
would be closed, too.
But what if you already have a foreground program running
and want it to run in the background instead? No problem:
gqview
<CTRL z>
[2]+ Stopped gqview
bg
[2]+ gqview &
The key combination <CTRL z> suspends
a program running on that terminal, so you can now use the bg
command to send it to the background.
Notice that there is a situation where starting a graphical
application from a terminal in the foreground is useful. This way all error
messages this application issues are printed to the terminal, and while they
might not be of use for you, they can provide useful hints of what's going
wrong to the person you ask for help when in trouble.
Some graphical programs, usually in their testing (or
Beta) period, still send messages to their controlling terminal even if they
have been backgrounded. If you are annoyed by this behavior, you can turn
it off with
command &>/dev/null &
This sends the program not only to the background, it
also sends all terminal output to the '/dev/null' file. '/dev/null' is the
system's data shredder, everything you send there promptly vanishes without
a trace.
section index top
Command substitution is a very handy feature. Let's
say you want to have a look at the 'README.mouse' file from the XFree86 documentation,
but you don't know where it is. Since you are a clever user, you've already
heard of the 'locate' command and have the 'slocate' package installed. So
you do a:
locate README.mouse
and you find out it is located in '/usr/X11R6/lib/X11/doc'.
Now you either use the terminal pager 'less' or your file manager to display
that file, providing that path. Command substitution makes that much easier
for you:
less $(locate README.mouse)
accomplishes the same in one step. The output
of the command 'locate README.mouse' (= /usr/X11R6/lib/X11/doc/README.mouse)
is used as the argument for the 'less' pager, which now displays this file.
The syntax for this mechanism is:
command1 $(command2)
Instead of '$()', you can use single backquotes:
command1 `command2`
That's less to type, but harder to read in scripts and
more easily to confuse with 'normal' single quotes, which the shell won't
accept as substitution indicators. I prefer the first method, but in the
end it's up to you.
Here's another example. Let's say you want to kill some
stubborn program called 'rob'. You can do this by finding out what its Process
ID is with the 'pidof' command and then issuing the 'kill' command with this
PID as its argument. Instead of typing
pidof rob
567
kill 567
you type
kill `pidof rob`
It is more efficient, isn't it?
On the next page, I'll introduce two more useful shell
mechanisms, file name globbing and output redirection.
section index top
Globbing and
redirecting
|