A shell does much more than simply run commands. It also has
powerful features to make this task easier: wildcards for matching
filenames, a “command history” to recall previous commands quickly,
pipes for making the output of one command become the input of
another, variables for storing values for use by the shell, and more.
Take the time to learn these features, and you will become faster and
more productive with Linux. Let’s skim the surface and introduce you
to these useful tools. (For full documentation, run info bash
.)
Wildcards are a shorthand for sets of files with similar
names. For example, a*
means all
files whose names begin with lowercase “a”. Wildcards are “expanded”
by the shell into the actual set of filenames they match. So if you
type:
$ ls a*
the shell first expands a*
into the filenames that begin with “a” in your current directory, as
if you had typed:
$ ls aardvark adamantium apple
ls
never knows you used a
wildcard: it sees only the final list of filenames after the shell
expands the wildcard. Importantly, this means
every Linux command, regardless of its origin,
works with wildcards and other shell features.
Wildcards never match two characters: a leading period, and
the directory slash (/
). These
must be given literally, as in .pro*
to match .profile, or /etc/*conf
to match all filenames ending
in conf in the /etc directory.
Wildcard |
Meaning |
---|---|
* |
Zero or more consecutive characters |
? |
Any single character |
[ |
Any single character
in the given |
[^ |
Any single character
not in the given
|
[! |
Same as |
When using character sets, if you want to include a literal
dash in the set, put it first or last. To include a literal closing
square bracket in the set, put it first. To include a ^
or !
symbol literally, don’t put it first.
Similar to wildcards, expressions with curly braces also expand to become multiple arguments to a command. The comma-separated expression:
{X,YY,ZZZ}
expands first to X, then YY, and finally ZZZ within a command line, like this:
$ echo sand{X,YY,ZZZ}wich sandXwich sandYYwich sandZZZwich
Braces work with any strings, unlike wildcards, which are limited to filenames. The preceding example works regardless of which files are in the current directory.
You can define variables and their values by assigning them:
$ MYVAR=3
To refer to a value, simply place a dollar sign in front of the variable name:
$ echo $MYVAR 3
Some variables are standard and commonly defined by your shell upon login.
Variable |
Meaning |
---|---|
The name of your X window display | |
Your home directory, such as /home/smith | |
Your login name, such
as | |
Your incoming mailbox, such as /var/spool/mail/smith | |
Your shell’s previous
directory, prior to the last | |
Your shell search path: directories separated by colons | |
Your shell’s current directory | |
The path to your shell, e.g., /bin/bash | |
The type of your terminal, e.g., xterm or vt100 | |
Your login name |
To see a shell’s variables, run:
$ printenv
The scope of the variable (i.e., which programs know about it)
is, by default, the shell in which it’s defined. To make a variable
and its value available to other programs your shell invokes (i.e.,
subshells), use the export
command:
$ export MYVAR
or the shorthand:
$ export MYVAR=3
Your variable is now called an environment
variable, since it’s available to other programs in your
shell’s “environment.” So in the preceding example, the exported
variable MYVAR
is available to
all programs run by that same shell (including shell scripts: see
Variables).
To make a variable value available to a specific program just
once, prepend variable=value
to the
command line:
$ printenv HOME
/home/smith
$ HOME=/home/sally
printenv HOME
/home/sally
$ printenv HOME
/home/smith The original value is unaffected
Programs are scattered all over the Linux filesystem, in
directories like /bin and
/usr/bin. When you run a
program via a shell command, how does the shell find it? The
critical variable PATH
tells the
shell where to look. When you type any command:
$ who
the shell has to find the who
program by searching through Linux
directories. The shell consults the value of PATH
, which is a sequence of directories
separated by colons:
$ echo $PATH /usr/local/bin:/bin:/usr/bin:/home/smith/bin
and looks for the who
command in each of these directories. If it finds who
(say, /usr/bin/who), it runs the command.
Otherwise, it reports:
bash: who: command not found
To add directories to your shell’s search path temporarily,
modify its PATH
variable. For
example, to append /usr/sbin to
your shell’s search path:
$ PATH=$PATH:/usr/sbin
$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/home/smith/bin:/usr/sbin
This change affects only the current shell. To make it
permanent, modify the PATH
variable in your startup file ~/.bash_profile, as explained in
Tailoring Shell Behavior. Then log out and log
back in.
The built-in command alias
defines a convenient shorthand for a longer command, to save typing.
For example:
$ alias ll='ls -l'
defines a new command ll
that runs ls -l
:
$ ll total 436 -rw-r--r-- 1 smith 3584 Oct 11 14:59 file1 -rwxr-xr-x 1 smith 72 Aug 6 23:04 file2 ...
Define aliases in your ~/.bashrc file (see Tailoring Shell Behavior) to be available whenever you
log in.[6] To list all your aliases, type alias
. If aliases don’t seem powerful
enough for you (since they have no parameters or branching), see
Programming with Shell Scripts, run info
bash
, and read up on “shell functions.”
The shell can redirect standard input, standard output, and standard error to and from files. In other words, any command that reads from standard input can have its input come from a file instead with the shell’s < operator:
$ mycommand < infile
Likewise, any command that writes to standard output can write to a file instead:
$ mycommand > outfile Create/overwrite outfile $ mycommand >> outfile Append to outfile
A command that writes to standard error can have its output redirected to a file as well, while standard output still goes to the screen:
$ mycommand 2> errorfile
To redirect both standard output and standard error to files:
$ mycommand > outfile 2> errorfile Separate files $ mycommand >& outfile Single file
You can redirect the standard output of one command to be the standard input of another, using the shell’s pipe (|) operator. For example:
$ who | sort
sends the output of who
into the sort
program, printing
an alphabetically sorted list of logged-in users. Multiple pipes
work too. Here we sort the output of who
again, extract the first column of
information (using awk
), and
display the results one page at a time (using less
):
$ who | sort | awk '{print $1}' | less
To invoke several commands in sequence on a single command line, separate them with semicolons:
$command1
;command2
;command3
To run a sequence of commands as before, but stop execution if
any of them fails, separate them with &&
(“and”) symbols:
$command1
&&command2
&&command3
To run a sequence of commands, stopping execution as soon as
one succeeds, separate them with ||
(“or”) symbols:
$command1
||command2
||command3
Normally, the shell treats whitespace simply as separating the words on the command line. If you want a word to contain whitespace (e.g., a filename with a space in it), surround it with single or double quotes to make the shell treat it as a unit. Single quotes treat their contents literally, while double quotes let shell constructs be evaluated, such as variables:
$ echo 'The variable HOME has value $HOME' The variable HOME has value $HOME $ echo "The variable HOME has value $HOME" The variable HOME has value /home/smith
Backquotes (“backticks”) cause their contents to be evaluated as a shell command. The contents are then replaced by the standard output of the command:
$ whoami Program that prints your username
smith
$ echo My name is `whoami`
My name is smith
If a character has special meaning to the shell but you want
it used literally (e.g., *
as a
literal asterisk rather than a wildcard), precede the character with
the backward slash “” character. This is called
escaping the special character:
$ echo a* As a wildcard, matching “a” filenames aardvark agnostic apple $ echo a* As a literal asterisk a* $ echo "I live in $HOME" Dollar sign means a variable value I live in /home/smith $ echo "I live in $HOME" A literal dollar sign I live in $HOME
You can also escape control characters (tabs, newlines, ^D,
and so forth) to have them used literally on the command line, if
you precede them with ^V
. This is
particularly useful for tab (^I
)
characters, which the shell would otherwise use for filename
completion (see Filename completion).
$ echo "There is a tab between here^V^I
and here"
There is a tab between here and here
Bash lets you edit the command line you’re working on, using keystrokes inspired by the text editors emacs and vi (see File Creation and Editing). To enable command-line editing with emacs keys, run this command (and place it in your ~/.bash_profile to make it permanent):
$ set -o emacs
For vi keys:
$ set -o vi
emacs keystroke |
vi keystroke (after ESC) |
Meaning |
---|---|---|
^P or up arrow |
k |
Go to previous command |
^N or down arrow |
j |
Go to next command |
^F or right arrow |
l |
Go forward one character |
^B or left arrow |
h |
Go backward one character |
^A |
0 |
Go to beginning of line |
^E |
$ |
Go to end of line |
^D |
x |
Delete next character |
^U |
^U |
Erase entire line |
You can recall previous commands you’ve run—that is, the shell’s history—and re-execute them. Some useful history-related commands are listed below.
Press the TAB key while you are in the middle of typing a filename, and the shell will automatically complete (finish typing) the filename for you. If several filenames match what you’ve typed so far, the shell will beep, indicating the match is ambiguous. Immediately press TAB again and the shell will present the alternatives. Try this:
$ cd /usr/bin $ ls un<TAB><TAB>
The shell will display all files in /usr/bin that begin with un, such as uniq, units, and unzip. Type a few more characters to disambiguate your choice and press TAB again.
3.16.81.94