Debian Tutorial (Obsolete Documentation)
Chapter 6 - Using the shell

6.1 Environment variables

Every process has an environment associated with it. An environment
is a collection of environment variables. A variable is a changeable
value with a fixed name. For example, the name EMAIL could refer
to the value joe@nowhere.com. The value can vary ---
EMAIL could also refer to jane@somewhere.com.

Since your shell is a process like any other, it has an environment. You can
view your shell's environment by entering the printenv command.
Here's some example output:

Environment variables are one way to configure the system. For example, the
EDITOR variable lets you select your preferred editor for posting
news, writing email, and so on. The HISTSIZE variable tells Bash
how many command lines to keep in its history; you can return to that many
command lines with the up arrow key.

Setting environment variables is simple. Once you learn how, you'll probably
want to set them automatically whenever you log on; see Customizing the shell, Chapter 9 for
instructions.

View the online manual for the less command. In order to show you
the text one screenful at a time, man invokes a pager
which shows you a new page of text each time you press the space bar. By
default, it uses the pager called more.

Go ahead and glance over the man page for less, which is an
enhanced pager. Scroll to a new page by pressing space; press q
to quit. more will also quit automatically when you reach the end
of the man page.

export PAGER=less

After reading about the advantages of less, you might want to use
it to read man pages. To do this, you set the environment variable
PAGER.

The command to set an environment variable within bash always has this format:
export NAME=value. If you happen to run
tcsh or another C Shell derivative, the equivalent command is
setenv NAMEvalue.

export means to move the variable from the shell into the
environment. This means that programs other than the shell will be able to
access it.

echo $PAGER

This is the easiest way to see the value of a variable. $PAGER
tells the shell to insert the value of the PAGER variable
before invoking the command. echo echoes back its
argument: in this case, the it echoes the current PAGER value,
less.

man more

Read the more manual. This time, man should have
invoked the less pager.

less has lots of features more lacks. For example,
you can scroll backward with the b key. You can also move up and
down (even sideways) with the arrow keys. less won't exit when it
reaches the end of the man page; it will wait for you to press q.

PAGER=more man more

If you want a different setting temporarily, you can put a new value in effect
for the current command line only. Put the
NAME=value at the start of the command line,
followed by the command to execute. Be sure to omit export.

You can try out some less-specific commands, like b,
to verify that they don't work with more and you are indeed using
more.

echo $PAGER

The value of PAGER should still be less; the above
setting was only temporary.

unset PAGER

If you don't want to specify a pager anymore, you can unset the
variable. man will then use more by default, just as
it did before you set the variable.

echo $PAGER

Since PAGER has been unset, echo won't print
anything.

PS1=hello:

Just for fun, change your shell prompt. $ should become
hello:.

export is not necessary, because we're changing the shell's own
behavior. There's no reason to export the variable into the environment for
other programs to see. Technically, PS1 is a shell
variable rather than an environment variable.

If you wanted to, you could export the shell variable,
transforming it into an environment variable. Then other programs could see
it: specifically, the children of the current shell process. The next
section explains this.

6.1.1 Parent and child processes

All processes come from an earlier process, called their parent
process. [10] The
ps command is a useful tool for exploring processes, and it can be
used to examine parent-child relationships.

ps f

This command asks to see a list of processes belonging to you, in a format that
shows how processes are related.

Here you can see that I have a number of processes running, including two
shells. The shells have child processes: shell process 7270 has child process
15980 (ps f) and shell 19682 has child process 15973 (man
ps). man ps has in turn invoked a complex set of
subprocesses in order to display a man page. Don't worry about what these
subprocesses do for now.

Parents and children have a complex relationship. Most of the time, when a
parent dies the child will die as well. So you can kill a whole set of
processes --- for example, all the man ps children in the above
example --- by killing the parent process, 15973.

Children inherit the environment variables of their parents, and some other
attributes such as the current working directory.

When a shell runs a command, it spawns the command as a child process. So the
man command inherits the shell's environment; if you've set the
PAGER variable, man will be able to see it.

If you fail to export a variable, only the shell itself will see
it, and it will not be passed on to children such as man.

6.2 Where commands live: the PATH variable

When you type a command into the shell, it has to find the program on your hard
disk before executing it. If the shell had to look all over the disk, it would
be very slow; instead, it looks in a list of directories contained in the
PATH environment variable. This list of directories makes up the
shells' search path; when you enter a command, it goes through each
one in turn looking for the program you asked to run.

You may need to change the PATH variable if you install programs
yourself in a nonstandard location.

The value of PATH is a colon-separated list of directories. The
default value on Debian systems is:

/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games

This value is defined in the file /etc/profile and applies to all
users. You can easily change the value, just as you can change any environment
variable.

If you type the command ls, the shell will first look in
/usr/local/bin; ls isn't there, so it will try
/usr/bin; when that fails, it will check /bin. There
it will discover /bin/ls, stop its search, and execute the program
/bin/ls. If /usr/bin/X11/ls existed (it doesn't, but
pretend), it would be ignored.

You can see which ls the shell is going to use with the
type command. type ls will give you the answer
/bin/ls --- try it yourself.

Try asking where type itself resides:

$ type type
type is a shell builtin

type isn't actually a program; it's a function provided by the
shell. However, you use it just like an external program. [11]

There are a number of commands like this; type man builtins to
read the man page describing them. In general, you don't need to know whether
a command is a builtin or a real program; however, builtins will not show up in
the output of ps or top since they aren't separate
processes. They're just part of the shell.

6.3 Aliases and shell functions

If you use the same command often, you might get tired of typing it.
bash lets you write shorter aliases for your commands.
You can also write shell functions, which are custom commands made up
of several other commands.

Say you always use the --almost-all and --color=auto
options to ls. You quickly get tired of typing ls
--almost-all --color=auto. So you make an alias:

alias myls='ls --almost-all --color=auto'

Now you can type myls instead of the full command. To see what
myls really is, run the command type myls. To see a
list of aliases you've defined, type simply alias on a line by
itself.

Shell functions are a little more flexible than aliases. An alias simply
substitutes a longer command when you type a shorter one. Functions let you
use a series of commands to perform some action.

First let's see how a shell function could be used in place of the above alias:

myls() {
ls --almost-all --color=auto $*
}

The above is called a function definition, because it gives a function
name (myls), then defines the meaning of the name (some commands
to execute). To define a function, write its name, followed by
(). Then include the commands to execute inside braces
({}). The portion inside braces is known as the body
of the function.

The arguments to the function can be referred to as $*. So if you
type:

myls /usr /etc

$* will be /usr /etc, the two arguments. If there
are no arguments, $* will be empty.

You can also refer to the arguments by number. So $1 in the
function body would be replaced by /usr, and $2 would
be replaced by /etc. Type in this function (you can type it at
the shell prompt; hit return after each line):

6.4 Controlling input and output

Stdin, stdout, pipelines, and redirection

Every process has at least three connections to the outside world. The
standard input is one source of the process's data; the standard
output is one place the process sends data; and the standard
error is a place the process can send error messages. (These are often
abbreviated stdin, stdout, and stderr.)

The words `source' and `place' are intentionally vague. These standard input
and ouput locations can be changed by the user; they could be the screen, the
keyboard, a file, even a network connection. The user can specify which
locations to use.

When you run a program from the shell, usually standard input comes from your
keyboard and standard output and error both go to your screen. However, you
can ask the shell to change these defaults.

For example, the echo command sends it output to standard output,
normally the screen. But you can send it to a file instead, with the
output redirection operator, '>'. For example, to put
the word "Hello" in the file myfile:

You can change the standard input of a command with the input redirection
operator, '<'. For example, more < myfile
will display the contents of myfile. This is not useful in
practice; for convenience, the more command accepts a filename
argument. So you can simply say more myfile and the effect will
be the same.

Under the hood, more < myfile means that the shell opens
myfile, then feeds its contents to the standard input of
more. more myfile, without the redirection operator,
means that the more command receives one argument,
myfile, opens the file itself, and then displays the file.

There's a reason for the double functionality, however. For example, you can
connect the standard output of one command to the standard input of another.
This is called a pipeline, and it uses the pipe operator,
'|'.

Perhaps you want to see the GNU General Public License in reverse. To do this,
you use the tac command (it's cat, only backward).
Try it out:

tac /usr/doc/copyright/GPL

Unfortunately, it goes by too quickly to read. So you only get to see a couple
of paragraphs. The solution is a pipeline:

tac /usr/doc/copyright/GPL | more

This takes the standard output of tac, which is the GPL in
reverse, and sends it to the standard input of more.

You can chain as many commands together as you like. Say you have an
inexplicable desire to replace every G with Q; for
this you use the command tr G Q, like this:

tac /usr/doc/copyright/GPL | tr G Q | more

You could get the same effect using temporary files and redirection. For
example:

6.5 Specifying how and when to run commands

"modifiers" like batch, at, nohup, nice

6.6 Filename expansion ("Wildcards")

Often you want a command to work with a group of files. "Wildcards"
are used to create a filename expansion pattern: a series of
characters and wildcards that expands to a list of filenames. For example, the
pattern /etc/* expands to a list of all the files in
/etc [12].
* is a wildcard which can stand for any series of characters, so
the pattern /etc/* will expand to a list of all the filenames
beginning with /etc/.

This filename list is most useful as a set of arguments for a command. For
example, the /etc directory contains a series of subdirectories
called rc0.d, rc1.d, etc. Normally to view the
contents of these, you would type:

/etc/rc?.d expands to a list of filenames which begin with
rc, followed by any single character, followed by .d.

Available wildcards are:

*

Matches any group of 0 or more characters

?

Matches exactly one character

[...]

If you enclose some characters in brackets, the result is a wildcard which
matches those characters. For example, [abc] matches either a, or
b, or c. If you add a ^ after the first bracket, the sense is
reversed; so [^abc] matches any character that is not a, b, or c.
You can include a range, such as [a-j], which matches anything
between a and j. The match is case sensitive, so to allow any letter, you must
use [a-zA-Z].

Expansion patterns are simple, once you see some concrete examples:

*.txt

This will give you a list of any filename which ends in .txt,
since the * matches anything at all.

*.[hc]

This gives a list of filenames which end in either .h or
.c.

a??

This gives you all three-letter filenames that begin with a.

[^a]??

This gives you all three-letter filenames that do not begin with
a.

a*

This gives you every filename that starts with a, regardless of
how many letters there are.

6.7 Interactive/non-interactive

Bash has two different modes: interactive and
non-interactive. Interactive means you can type into it, and have it
do things for you. Non-interactive shells interpret shell scripts, similar to
DOS batch files. You give it a list of commands to carry out, and it goes and
does them, but without your intervention. You don't see all the commands being
typed in, Of course any output will be recorded somewhere (the standard output,
or stdout, normally the screeen or a log file). We will get more into
non-interactive shells a little later on.

6.7.1 Interactive shells

Interactive shells will take a very long time for one to master, just because
they're so powerful --- you'll probably never learn everything! There is just
so much out there that a shell can do, and of course it's always changing. We
will talk about bash here, and some basic commands that will make
your life with a shell easier. In bash, one can have several different things
going on all at once, and this can get confusing.

A shell is a Line Oriented or command line environment. The shell will always
prompt you with a prompt, whenever it is waiting on you to do things. The
default debian prompt is a $. At the $ prompt is where you can type in
commands to tell linux to do things, it can be a program name, or it can be a
"builtin" command that the shell provides for your convenience.