Selected Features of the bash Shell

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

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

[set]

Any single character in the given set, most commonly a sequence of characters, like [aeiouAEIOU] for all vowels, or a range with a dash, like [A-Z] for all capital letters

[^set]

Any single character not in the given set (as in the earlier example)

[!set]

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.

Brace expansion

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.

Shell variables

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

DISPLAY

The name of your X window display

HOME

Your home directory, such as /home/smith

LOGNAME

Your login name, such as smith

MAIL

Your incoming mailbox, such as /var/spool/mail/smith

OLDPWD

Your shell’s previous directory, prior to the last cd command

PATH

Your shell search path: directories separated by colons

PWD

Your shell’s current directory

SHELL

The path to your shell, e.g., /bin/bash

TERM

The type of your terminal, e.g., xterm or vt100

USER

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

Search path

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.

Aliases

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.”

Input/output redirection

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

Pipes

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

Combining commands

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

Quoting

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

Escaping

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

Command-line editing

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

Command history

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.

Command

Meaning

history

Print your history

history N

Print the most recent N commands in your history

history -c

Clear (delete) your history

!!

Re-run previous command

!N

Re-run command number N in your history

!-N

Re-run the command you typed N commands ago

!$

Represents the last parameter from the previous command; great for checking that files are present before removing them:

$ ls a*
acorn.txt   affidavit
$ rm !$

!*

Represents all parameters from the previous command:

$ ls a b c
a   b   c
$ wc !*
   103    252   2904 a
    12     25    384 b
 25473  65510 988215 c
 25588  65787 991503 total

Filename completion

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.



[6] Some setups use a separate file, ~/.bash_aliases, for this purpose.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.81.94