GNU Bash Usage 101
For the really in-depth stuff, read the
GNU Bash Reference Manual,
or even just
bash(1), which is stupidly detailed. This is intended
to be a quick introduction; for more advanced things like using the shell for
automation through scripting, additional reading will be required.
The Shell Prompt
When a command-line system wants you to do something, it will prompt you, by issuing a command-line prompt on the screen. While the exact form of the prompt differs between systems, it often starts out with something simple, such as the following:
[mbt@borgripper ~]$ _
Within square brackets appears my username and the system’s hostname, as well
as the directory that I am in (in this case, ~, which means
which for me is
/home/mbt). The underscore represents where the terminal’s
blinking cursor would be located.
The shell has the single fundamental job of taking user input and acting on it. User input can happen at the command line itself, or in the form of shell scripts, which are used to perform complex jobs using a single command.
Commands on UNIX systems are simply executable binary programs or scripts (including shell scripts). Such files are marked as executable on the filesystem, meaning that you can run them by typing the path to the command.
For example, the
ls(1) program is often installed in
/usr/bin, so it can be
run as follows:
[mbt@borgripper ~]$ /usr/bin/ls [ ... output from file listing omitted ...]
Of course, it would be inconvenient to type
/usr/bin/ls every time, so the
shell has the notion of the
PATH is a shell variable that
holds a list of directories. When you type a command name that does not
include any path information, the shell will search these directories (in order)
until one of the following happens:
- The shell finds the executable file, and asks the OS to run it.
- The shell does not find the executable file and returns an error.
- The shell finds a matching file, but the file is not executable and so it returns an error.
This means that:
[mbt@borgripper ~]$ ls [ ... output from file listing omitted ...]
… will work as long as
ls(1) is found in one of the directories present in
PATH variable, and is executable.
As you’ll see later, variables play a major role in the shell. However, they
are complex enough that we’ll only worry about the
PATH variable for now.
“Pipelines”, a.k.a. The UNIX Way
One of the most powerful features of modern shells is the ability to create complex “one-liner” scripts that perform larger tasks than any of the single commands could do on its own.
[mbt@borgripper ~]$ cat /proc/cpuinfo | grep ^processor | wc -l 32
The result is that
grep(1) filters out all of the lines except those
that begin with the word “processor”, and
wc(1) then counts how many
lines are output. The knowledge that the answer is correct, of course, depends
on the knowledge that the special file
/proc/cpuinfo will always be laid out
in a manner which allows this command to operate successfully.
A pipeline can be thought of as a “connection” from one program’s standard output to another program’s standard input (which, along with standard error are known as a program’s stdio).
There are two types of variables in the shell:
- Local, or non-exported, shell variables, and
- Environment, or exported, shell variables.
Environment variables are visible to programs executed by the shell; local variables are not.
Viewing a Variable
To look at the value of a variable, the following command can be given at the shell prompt:
[mbt@borgripper ~]$ printf "%s\n" "$PATH" /home/mbt/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin
Setting a Variable
To set the value of a variable, the following command can be given at the shell prompt:
[mbt@borgripper ~]$ VARIABLENAME='a string value' [mbt@borgripper ~]$ _
To export that variable into the environment, do it like this:
[mbt@borgripper ~]$ VARIABLENAME='a string value' [mbt@borgripper ~]$ export VARIABLENAME [mbt@borgripper ~]$ _
When the shell has finished running a single statement, a numeric result is returned. Conventionally, the result zero means “success,” which non-zero return codes indicate “failure” of some sort or another.
The return value of the previously evaluated statement is stored in the special
?, which can be inspected as follows:
[mbt@borgripper ~]$ printf "%s\n" "$?" 0 [mbt@borgripper ~]$ _
Often, you can press the
TAB key on the keyboard once or twice and the shell
will “help you out” by showing a list of possibilities. For example:
[mbt@borgripper ~]$ ls<TAB><TAB> ls lsblk lsinitcpio lskat lslogins lsmod lspci lsusb lsattr lscpu lsipc lslocks lsmem lsns lspcmcia lsusb.py [mbt@borgripper ~]$ ls_
In this way, you can determine what programs are available, one prefix at a time.