Total Pageviews

Search: This Blog, Linked From Here, The Web, My fav sites, My Blogroll

07 February 2011

Bash Bourne Again SHell in UNIX

"Under Linux there are GUIs (graphical user interfaces), where you can point and click and drag, and hopefully get work done without first reading lots of documentation. The traditional Unix environment is a CLI (command line interface), where you type commands to tell the computer what to do. That is faster and more powerful, but requires finding out what the commands are."

Basics

Short History
The Bourne Again shell (named in punning tribute to Steve Bourne's shell) was created for use in the GNU project. GNU is a recursive acronym, standing for "GNU's Not UNIX."
The GNU project was started by Richard Stallman of the Free Software  Foundation (FSF) for the purpose of creating a UNIX-compatible operating system and replacing all of the commercial UNIX utilities with freely distributable ones. GNU embodies not only new software utilities, but a new distribution concept: the copyleft. Copylefted software may be freely distributed so long as no restrictions are placed on further distribution (for example, the source code must be made freely available).
bash, intended to be the standard shell for the GNU system, was officially "born" on Sunday,10  January, 1988. Brian Fox wrote the original versions of bash and readline library(provides line-editing and history capabilities for interactive programs) and continued to improve the shell up until 1993. Early in 1989 he was joined by Chet Ramey, who was responsible for numerous bug fixes and the inclusion of many useful features.
Chet Ramey is now the official maintainer of bash and continues to make further enhancements.
In keeping with the GNU principles, all versions of bash since 0.99 have been freely available from the FSF. bash has found its way onto every major version of UNIX and is rapidly becoming the most popular Bourne shell derivative. It is the standard shell included with Linux, a widely used free UNIX operating system, and Apple's Mac OS X.

In 1995 Chet Ramey began working on a major new release, 2.0, which was released to the public for the first time on 23 December, 1996. bash 2.0 added a range of new features to the old release (the one before being 1.14.7) and brought the shell into better compliance with various standards. bash 3.0 and 4.0 improves on the previous version and rounds out the feature list and standards compliance.


Features
The Bourne shell is still known as the "standard" shell, but bash is becoming increasingly popular. In addition to its Bourne shell compatibility, it includes the best features of the C and Korn shells as well as several advantages of its own.
  • command-line editing modes (it's much easier to go back and fix mistakes or modify previous commands than it is with the C shell's history mechanism and the Bourne shell doesn't let you do this at all)
  • job control ( job control gives you the ability to stop, start, and pause any number of commands at the same time). This feature was borrowed almost verbatim from the C shell. 
  • for shell customizers and programmers: many new options and variables for customization, and its programming features have been significantly expanded to include function definition, more control structures, integer arithmetic, advanced I/O control, etc.


Bash in your system
I you have or not bash right now depends on your Linux distribution and how your system administrator set your account up(what shell he uses as the "standard" on the system). You may have more than one shell available. It's easy for you to determine what your current login shell is.


To install bash as your login shell:

1. find where is bash in the system hierarchy (/bin or /usr/local/bin)
$ grep bash /etc/passwd | awk -F: '{print $7}' | sort -u/bin/bash

2. install bash as your login shell or equivalently trough chsh as superuser if not you're claimed for a password or you get an error "chsh: user '/bin/bash' does not exist" (For system security reasons, only certain programs are allowed to be installed as login shells.)
$ chsh /bin/bash
Password: 
then log out and log back in again (or type reset) to start using bash.


Interactive shell
The shell is meant interactive, if you engage in a login session that begins when you log in(or open a Terminal window in a gui environment) and ends when you type exit or logout or press CTRL-D (The shell can be set up so that it ignores a single CTRL-D to end the session erroneously).

During a login session, by default, the shell prompts you for each command with an information string followed by a dollar sign (shell prompts can be tuned by user taste), you type in command lines (lines of text ending in RETURN(Enter) that you type in to your terminal emulator) to the shell.

A shell command line consist of one or more words separated , by blanks or TABs.
  1. The first word on the line is the command
  2. Optionally there are one or more options. An option is a special type of argument. Options usually consist of a dash followed by a letter or (in gnu's extended form) a double dash followed by a word. Sometimes options take their own arguments.
  3. The rest (if any) are arguments (also called parameters) to the command, which are names of things on which the command will act.


Files
Anything on any UNIX system is a file. A file can contain any kind of information, so there are different types of files. Three types are by far the most important:
  1. Regular files : like  text files
  2. Executable files: programs(not human readable) and shell scripts (human readable)
  3. Directories: folders that contain other files and/or possibly other directories (called Subdirectories). That leads to a hierarchical structure, known as a tree, for all files on a UNIX system.

Directories
The top of the tree is a directory called root that has no name on the system.  All files can be named by expressing their location on the system relative to root(absolute pathname); i.e. /home/dir1/dir2/file_name
Most UNIX tutorials say that root directory has the name /

The working (or current) directory
Is a concept that attempt simplify naming files. Mean which is the directory you are "in" at any given time.
If you give a pathname with no leading slash, then the location of the file is worked out relative to the working directory(relative pathnames)
 When you log in to the system, your working directory is initially set to a special directory called your home (or login) directory. Per default every bash command acts on files in your home directory.
System administrators often set up the system so that everyone's home directory name is the same as their login name, and all home  directories are contained in a common directory (/home) under root.
 
Tilde
Home directories occur often in pathnames. Although many systems are organized so that all home directories have a common parent (such as /home or /users), you should not rely on that being the case, nor should you even have to know the absolute pathname of someone's home directory.

Bash has a shortcut for home directories: just precede the name of the user with a tilde (~).
~user/pathname is an absolute pathname, so it doesn't matter what your working directory is when you use it.
A tilde by itself refers to your own home directory. 
You can refer to a file in your home directory as ~/file_name (notice the difference between that and ~file_name, which the shell would try to interpret as user file_name's home directory). If file_name is in your /dir subdirectory, then you can call it ~/dir/file_name.
This notation is handiest when your working directory is not in your home directory tree, e.g., when it's some system directory like /tmp.

Changing working directories
If you don't remember your working directory, the command pwd tells the shell to print it.

cd takes as an argument the name of the directory you want to become your working directory.
  1. It can be relative to your current directory
  2. it can contain a tilde
  3. it can be absolute (starting with a slash)
  4. If you omit the argument, cd changes to your home directory (i.e., it's the same as cd ~ ).
  5. .. (dot dot): means "parent of this directory." Every directory has one of these except of /. 
  6. . (single dot):  means "this directory." Thus, cd . effectively does nothing.
  7. cd - : changes to whatever directory you were in before the current one.


Wildcard, Pathname, Brace Expansion
Sometimes you want to verify the existence of a certain group of files without having to know all of their names; for example, you might want to see which files in your current directory have names that end in .txt.

Filenames are so important in UNIX that the shell provides a built-in way to specify the pattern of a set of filenames without having to know all of the names themselves. You can use special characters, called wildcards, in filenames to turn them into patterns. The most basic are:
  1. ?                : Any single character
  2. *                : Any string of characters
  3. [set], [!set] : Any character in set,  Any character not in set 
 NOTE: MS-DOS and VAX/VMS users should note that there is nothing special about the dot (.) in UNIX filenames (aside from the leading dot, which "hides" the file); it's just another character. For example, ls * lists all files in the current directory; you don't need *.* as you do on other systems. Indeed, ls *.* won't list all the files only those that have at least one dot in the middle of the name.

Notice that when * not expand (because of lack filenames that match ) shell leaves the string with the wildcard untouched.
This is different from the C shell's wildcard mechanism, which prints an error message and doesn't execute the command at all.
The process of matching expressions containing wildcards to filenames is called Wildcard expansion known also as globbing. Wildcard expansion is part of a more general concept called pathname expansion (ls /usr*/[be]*).Instead in tilde expansion, tildes are replaced with home directories where applicable.


It's important to be aware that the commands that you run only see the results of wildcard expansion. That is, they just see a list of arguments, and they have no knowledge of how those arguments came into being.

In the set construct we can have a list of characters (e.g., abc), an inclusive range (e.g., a-z), or some combination of the two.
  • If you want the dash character to be part of a list, just list it first or last. 
  • If you want the "!" character to be part of a list, place it after the first character in the set  or precede it with a backslash, as in [\!]. 
Don't use ranges on punctuation characters or mixed-case letters: e.g., [a-Z] and [A-z] should not be trusted to include all of the letters and nothing more. The problem is that such ranges are not entirely portable between different types of computers.
Specifically, ranges depend on the character encoding scheme your computer uses (normally ASCII, but IBM mainframes use EBCDIC) and the character set used by the current locale (ranges in languages other than English may not give expected results).
Whereas pathname expansion wildcards will expand to files and directories that exist, brace expansion expands to an arbitrary string of a given form: an optional preamble, followed by comma-separated strings between braces, and followed by an optional postscript.
$ harrykar@harrysas:~$ echo b{ed,olt,ar}s
beds bolts bars
harrykar@harrysas:~$ echo b{ar{d,n,k},ed}s
bards barns barks beds
harrykar@harrysas:~$ echo {2..5}
2 3 4 5
harrykar@harrysas:~$ echo {d..h}
d e f g h

Notice that these are not filenames the strings produced are independent of filenames.
The last form of brace expansion in the example above is not available in bash prior to Version 3.0.
bash and C shell brace expansion differs slightly. bash requires at least one unquoted comma to perform an expansion; otherwise, the word is left unchanged, e.g., b{o}lt remains as b{o}lt.


I/O
The UNIX I/O scheme is of  those few occasions when someone (i.e., not a committee) comes up with an idea that is small in concept yet enormous in its implications like LISP language, the relational data model, and object-oriented programming.

The UNIX I/O scheme is based on two dazzlingly simple ideas.
  1. UNIX file I/O takes the form of byte-streams (arbitrarily long sequences of characters (bytes) without any further structure)
  2. everything on the system that produces or accepts data is treated as a file; this includes hardware devices like disk drives and terminals.
Both of these ideas have made systems programmers' lives much more pleasant.

Standard I/O
By convention, each UNIX program has
  1. a single way of accepting input called standard input
  2. a single way of producing output called standard output, and 
  3.  a single way of producing error messages called standard error output, usually shortened to standard error
Of course, a program can have other input and output sources as well.
All shells handle standard I/O in basically the same way. Each program that you invoke has all three standard I/O channels set to your terminal, so that
  1. standard input is your keyboard, and 
  2. standard output and error are your screen or window

Standard I/O was the first scheme of its kind that was designed specifically for interactive users at terminals, rather than the older batch style of use that usually involved decks of punch-cards. Since the UNIX shell provides the user interface, standard I/O was designed to fit in very neatly with the shell.


When necessary, you can redirect input and output to come from or go to a file instead. You can also hook programs together in a pipeline, in which the standard output of one program feeds directly into the standard input of another.This makes it possible to use UNIX utilities as building blocks for bigger programs.

Many UNIX utility programs are meant to be used in this way: they each perform a specific type of filtering operation on input text. The more popular filtering utilities are:
  1. cat       : Copy its input to its output
  2. grep     : Search for strings in the input
  3. sort      : Sort lines in the input and print them sorted in output
  4. cut       : Extract columns from input
  5. sed       : Perform editing operations on input
  6. tr          : Translate characters in the input to other characters 
they take names of input files as arguments and produce output on standard output. You may know, however, that all of them (and most other UNIX utilities) accept input from standard input if you omit the argument
If a particular UNIX utility doesn't accept standard input when you leave out the filename argument, try using a dash (-) as the argument. Some UNIX systems provide standard input as a file, so you could try providing the file /dev/stdin as the input file argument.

I/O Redirection

cat is short for "catenate," i.e., link together. It accepts multiple filename arguments and copies them to the standard output. But let's pretend, for now, that cat and other utilities don't accept filename arguments and accept only standard input.
As we said above, the shell lets you redirect standard input so that it comes from a file. The notation command < filename does this; it sets things up so that command takes standard input from a file instead of from a terminal. 
Input and output redirectors can be combined. For example: the cp command is normally used to copy files; if for some reason it didn't exist or was broken, you could use cat in this way:
$ cat <  file1  >  file2 

This would be similar to
$ cp file1 file2 

Pipelines
It is also possible to redirect the output of a command into the standard input of another command instead of a file. The construct that does this is called the pipe, notated as |.
A command line that includes two or more commands connected with pipes is called a pipeline
Pipes are often used with the more command, which works just like cat except that it prints its output screen by screen, pausing for the user to type SPACE (next screen), RETURN (next line), or other commands. If you're in a directory with a large number of files and you want to see details about them,
$ ls -l | more
 will give you a detailed listing a screen at a time.

Pipelines can get very complex, and they can also be combined with other I/O directors. To see a sorted listing of a file a screen at a time, type:
$ sort < file | more

To print it instead of viewing it on your terminal, type:
$ sort < file | lp


Here's a more complicated example. The file /etc/passwd stores information about users' accounts on a UNIX system. Each line in the file contains a user's login name, user ID number, encrypted password, home directory, login shell, and other information.
$ cut -d: -f1 < /etc/passwd | sort

The cut command extracts the first field (-f1), where fields are separated by colons (-d:), from the input. The entire pipeline will print a sorted listing of all users on the system.

If you want to send the list directly to the printer (instead of your screen), you can extend the pipeline like this:
$ cut -d: -f1 < /etc/passwd | sort | lp

Now you should see how I/O directors and pipelines support the UNIX building block philosophy. The notation is extremely terse and powerful.
Just as important, the pipe concept eliminates the need for messy temporary files to store command output before it is fed into other commands.


Background jobs

Pipes are a special case of a more general feature: doing more than one thing at a time(multiprogramming).
This is a capability that many other commercial operating systems don't have, because of the rigid limits that they tend to impose upon users. UNIX, on the other hand, was developed in a research lab and meant for internal use, so it does relatively little to impose limits on the resources available to users on a computer as usual, leaning towards uncluttered simplicity rather than overcomplexity.
"Doing more than one thing at a time" means running more than one program at the same time. You do this when you invoke a pipeline; you can also do it by logging on to a UNIX system as many times simultaneously as you wish. (If you try that on an IBM's VM/CMS system, for example, you will get an obnoxious "already logged in" message.)

The shell also lets you run more than one command at a time during a single login session. Normally, when you type a command and hit RETURN, the shell will let the command have control of your terminal until it is done; you can't type in further commands until the first one is done.

But if you want to run a command that does not require user input and you want to do other things while the command is running, put an ampersand (&) after the command.
This is called running the command in the background, and a command that runs in this way is called a background job; by contrast, a job run the normal way is called a foreground job. When you start a background job, you get your shell prompt back immediately, enabling you to enter other commands.

The most obvious use for background jobs is programs that take a long time to run, such as sort or uncompress on large files.
harrykar@harrysas:~$ tar xvf file.tar &
[1] 175
harrykar@harrysas:~$ 
harrykar@harrysas:~$ jobs
[1]+ Running tar xvf file.tar &
harrykar@harrysas:~$
[1]+ Done tar xvf file.tar

[1] 175 is the job number matter job reference
You can check on background jobs with the command jobs.
When the job finishes, you will see a message like [1]+ Done tar xvf file.tar. The message changes if your background job terminated with an error;

Background I/O
Jobs you put in the background should not do I/O to your terminal. By definition, a background job doesn't have control over your terminal. Among other things, this means that only the foreground process (or, if none, the shell itself) is "listening" for input from your keyboard. If a background job needs keyboard input, it will often just sit there doing nothing until you do something about it .

If a background job produces screen output, the output will just appear on your screen. If you are running a job in the foreground that produces output too, then the output from the two jobs will be randomly (and often annoyingly) interspersed.
If you want to run a job in the background that expects standard input or produces standard output, you usually want to redirect the I/O so that it comes from or goes to a file. 
Programs that produce small, one-line messages (warnings, "done" messages, etc.) are an exception to this general rule; you may not mind if these are interspersed with whatever other output you are seeing at a given time.
For example, the diff utility examines two files, whose names are given as arguments, and prints a summary of their differences on the standard output. If the files are exactly the same, diff is silent. Usually, you invoke diff expecting to see a few lines that are different.
diff, like sort and tar, can take a long time to run if the input files are very large.

Background Jobs and Priorities
Background jobs can save you a lot of thumb-twiddling time. Just remember that such jobs eat up lots of system resources like memory and the processor (CPU).
Just because you're running several jobs at once doesn't mean that they will run faster than they would if run sequentially in fact, performance is usually slightly worse.
Every job on the system is assigned a priority, a number that tells the operating system how much priority to give the job when it doles out resources (the higher the number, the lower the priority). Commands that you enter from the shell, whether foreground or background jobs, usually have the same priority.
The system administrator is able to run commands at a higher priority than normal users. If you are a system administrator logged in as root, then you can also use nice to raise a job's priority.
Note that if you're on a multiuser system, running lots of background jobs may eat up more than your fair share of resources, and you should consider whether having your job run as fast as possible is really more important than being a good citizen. nice lets you lower the priority of any job(Complex commands following nice should be quoted)


Quoting
Quoting is called when sometimes you will want to use special characters literally, i.e., without their special meanings in shell.
If you surround a string of characters with single quotation marks (or quotes), you strip all characters within the quotes of any special meaning they might have.
The most obvious situation where you might need to quote a string is with the echo command, which just takes its arguments and prints them to the standard output.
$ echo '2 * 3 > 5' is a valid inequality.

singe quotes are stronger (mean manage all special characters as special) than double quotes

Backslash-Escaping
Another way to change the meaning of a character is to precede it with a backslash (\). This is called backslash-escaping the character. In most cases, when you backslash-escape a character, you quote it. For example:
$ echo 2 \* 3 \> 5 is a valid inequality

will produce the same results as if you surrounded the string with single quotes.

To use a literal backslash, just surround it with quotes ('\') or, even better, backslash-escape it (\\).  A few UNIX commands take arguments that often include wildcard characters, which need to be escaped so the shell doesn't process them first. The most common such command is find, which searches for files throughout entire directory trees.

To use find, you supply the root of the tree you want to search and arguments that describe the characteristics of the file(s) you want to find. For example, the command:
$ find . -name string

searches the directory tree whose root is your current directory for files whose names match the string. (Other arguments allow you to search by the file's size, owner, permissions, date of last access, etc.)

You can use wildcards in the string, but you must quote them, so that the find command itself can match them against names of files in each directory it searches. The command:
$ find . -name `*.c'

will match all files whose names end in .c anywhere in your current directory, subdirectories, sub-subdirectories, etc.


Quoting Quotation Marks
You can also use a backslash to include double quotes within a quoted string. For example:
$ echo \"2 \* 3 \> 5\" is a valid inequality
"2 * 3 > 5" is a valid inequality


However, this won't work with single quotes inside quoted expressions. For example:
$ echo 'Hatter\'s tea party'
> 

will not give you Hatter's tea party. You can get around this limitation in various ways. First, try eliminating the quotes:
$ echo Hatter\'s tea party
Hatter's tea party


If no other characters are special (as is the case here), this works. Otherwise, you can use the following command:
$ echo 'Hatter'\''s tea party'
Hatter's tea party

That is, `\'' (i.e., single quote, backslash, single quote, single quote) acts like a single quote within a quoted string. Why? The first ' in `\'' ends the quoted string we started with (`Hatter), the \' inserts a literal single quote, and the next ' starts another quoted string that ends with the word "party".

Continuing Lines
A related issue is how to continue the text of a command beyond a single line on your terminal window. The answer is conceptually simple: just quote the RETURN key. After all, RETURN is really just another character.
You can do this in two ways: by ending a line with a backslash, or by not closing a quote mark (i.e., by including RETURN in a quoted string). If you use the backslash, there must be nothing between it and the end of the line not even spaces or TABs.


Whether you use a backslash or a single quote, you are telling the shell to ignore the special meaning of the RETURN character. After you press RETURN, the shell understands that you haven't finished your command line (i.e., since you haven't typed a "real" RETURN), so it responds with a secondary prompt, which is > by default, and waits for you to finish the line. You can continue a line as many times as you wish.
$ echo The Caterpillar and Alice looked at each other for some \ 
> time in silence: at last Caterpillar took the hookah out of its \
> mouth, and addressed her in a languid, sleepy voice.

or
$ echo 'The Caterpillar and Alice looked at each other for some
> time in silence: at last Caterpillar took the hookah out of its
> mouth, and addressed her in a languid, sleepy voice.' 


Control Keys

RETURN is actually the same as CTRL-M. DEL and CTRL-? idem.
Perhaps the most difficult thing about control keys is that they can differ from system to system. The usual arrangement is shown in table.
You can use the stty command to find out what your settings are and change them if you wish; If your UNIX version derives from System III or System V (this includes AIX, HP/UX, SCO, Linux, and Xenix), type
$ stty -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?;
swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke


CTRL-C, sometimes called the interrupt key. This stops or tries to stop the command that is currently running. Sometimes CTRL-C doesn't work; in that case, if you really want to stop a job, try CTRL-\.

When you are running a command that accepts standard input from your keyboard, CTRL-D tells the process that your input is finished as if the process were reading a file and it reached the end of the file. Most utilities that accept standard input understand CTRL-D as the end-of-input character, though many such programs accept commands like q, quit, exit, etc. On a blank line is the same as the exit command. Otherwise, it deletes the character in front of the cursor.

CTRL-S and CTRL-Q are called flow-control characters. They represent an antiquated way of stopping and restarting the flow of output from one device to another (e.g., from the computer to your terminal) that was useful when the speed of such output was low. They are rather obsolete in these days of high-speed networks. In fact, under the latter conditions, CTRL-S and CTRL-Q are basically a nuisance. The only thing you really need to know about them is that if your screen output becomes "stuck," then you may have hit CTRL-S by accident. Type CTRL-Q to restart the output; any keys you may have hit in between will then take effect.

The final group of control characters gives you rudimentary ways to edit your command line. DEL acts as a backspace key (in fact, some systems use the actual BACKSPACE or CTRL-H key as "erase" instead of DEL); CTRL-U erases the entire line and lets you start over. Again, these have been superseded.
Why are so many outmoded control keys still in use? They have nothing to do with the shell per se; instead, they are recognized by the tty driver, an old and hoary part of the operating system's lower depths that controls input and output to/from your terminal.


Help

A unique feature in bash is an online help system. The help command gives information on commands in bash. If you type help by itself, you'll get a list of the built-in shell commands along with their options.
$  help
GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
These shell commands are defined internally.  Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.

A star (*) next to a name means that the command is disabled.

 job_spec [&]                            history [-c] [-d offset] [n] or hist>
 (( expression ))                        if COMMANDS; then COMMANDS; [ elif C>
 . filename [arguments]                  jobs [-lnprs] [jobspec ...] or jobs >
 :                                       kill [-s sigspec | -n signum | -sigs>
 [ arg... ]                              let arg [arg ...]
 [[ expression ]]                        local [option] name[=value] ...
 alias [-p] [name[=value] ... ]          logout [n]
 bg [job_spec ...]                       mapfile [-n count] [-O origin] [-s c>
 bind [-lpvsPVS] [-m keymap] [-f filen>  popd [-n] [+N | -N]
 break [n]                               printf [-v var] format [arguments]
 builtin [shell-builtin [arg ...]]       pushd [-n] [+N | -N | dir]
 caller [expr]                           pwd [-LP]
 case WORD in [PATTERN [| PATTERN]...)>  read [-ers] [-a array] [-d delim] [->
 cd [-L|-P] [dir]                        readarray [-n count] [-O origin] [-s>
 command [-pVv] command [arg ...]        readonly [-af] [name[=value] ...] or>
 compgen [-abcdefgjksuv] [-o option]  >  return [n]
 complete [-abcdefgjksuv] [-pr] [-DE] >  select NAME [in WORDS ... ;] do COMM>
 compopt [-o|+o option] [-DE] [name ..>  set [--abefhkmnptuvxBCHP] [-o option>
 continue [n]                            shift [n]
 coproc [NAME] command [redirections]    shopt [-pqsu] [-o] [optname ...]
 declare [-aAfFilrtux] [-p] [name[=val>  source filename [arguments]
 dirs [-clpv] [+N] [-N]                  suspend [-f]
 disown [-h] [-ar] [jobspec ...]         test [expr]
 echo [-neE] [arg ...]                   time [-p] pipeline
 enable [-a] [-dnps] [-f filename] [na>  times
 eval [arg ...]                          trap [-lp] [[arg] signal_spec ...]
 exec [-cl] [-a name] [command [argume>  true
 exit [n]                                type [-afptP] name [name ...]
 export [-fn] [name[=value] ...] or ex>  typeset [-aAfFilrtux] [-p] name[=val>
 false                                   ulimit [-SHacdefilmnpqrstuvx] [limit>
 fc [-e ename] [-lnr] [first] [last] o>  umask [-p] [-S] [mode]
 fg [job_spec]                           unalias [-a] name [name ...]
 for NAME [in WORDS ... ] ; do COMMAND>  unset [-f] [-v] [name ...]
 for (( exp1; exp2; exp3 )); do COMMAN>  until COMMANDS; do COMMANDS; done
 function name { COMMANDS ; } or name >  variables - Names and meanings of so>
 getopts optstring name [arg]            wait [id]
 hash [-lr] [-p pathname] [-dt] [name >  while COMMANDS; do COMMANDS; done
 help [-dms] [pattern ...]               { COMMANDS ; }

You can also provide help with a partial name, in which case it will return details on all commands matching the partial name.  The partial name can also include wildcards. You'll need to quote the name to ensure that the wildcard is not expanded to a filename.

Sometimes help will show more than a screenful of information and it will scroll the screen. You can use the more command to show one screenful at a time by typing help command | more.


Command-Line Editing

If you are an experienced Bourne shell user, undoubtedly you know the frustration of having to retype long command lines. You can use the BACKSPACE key to edit, but once you hit RETURN, it's gone forever! The C shell provided a small improvement via its history mechanism, which provides a few very awkward ways of editing previous commands.

Bash  has editing modes that allow you to edit command lines with editing commands similar to those of the two most popular UNIX editors, vi and emacs.
You may be wondering why these two editors were chosen. The primary reason is because vi and emacs are the most widely used editors for UNIX. People who have used either editor will find familiar editing facilities.
It also provides a much-extended analog to the C shell history mechanism called fc (fix command) that, among other things, allows you to use your favorite editor directly for editing your command lines. To round things out, bash also provides the original C shell history mechanism.

Both emacs and vi modes introduce the potential for clashes with control keys (look table above) set up by the UNIX terminal interface.
Bash initially starts interactively with emacs-mode as the default (unless you have started bash with the -noediting option;
If you are not familiar with either of these editors, you should seriously consider adopting emacs-mode keyboard habits. Because it is based on control keys and doesn't require you to think in vi's "command mode" and "insert mode", you will find emacs-mode easier to assimilate. Although the full emacs is an extremely powerful editor, its command structure lends itself very well to small subsetting: there are several "mini-emacs" editors floating around for UNIX, MS-DOS, and other systems.

The same cannot be said for vi, because its command structure is really meant for use in a full-screen editor. vi is quite powerful too, in its way, but its power becomes evident only when it is used for purposes similar to that for which it was designed: editing source code in C and LISP. As mentioned earlier, a vi user has the power to move mountains in few keystrokes but at the cost of being unable to do anything meaningful in very few keystrokes. Unfortunately, the latter is most desired in a command interpreter, especially nowadays when users are spending more time within applications and less time working with the shell. In short, if you don't already know vi, you will probably find its commands obscure and confusing.

There are two ways to enter either editing mode while in the shell:
  1. use the set command
  2. set a readline variable in the file .inputrc

$ set -o emacs
or
$ set -o vi


The History List
Whenever you log in or start another interactive shell, bash reads an initial history list from the file .bash_history in your home directory.
From that point on, every bash interactive session maintains its own list of commands. 
When you exit from a shell, it saves the list in .bash_history. You can call this file whatever you like by setting the environment variable HISTFILE.

emacs Editing Mode
If you are an emacs user, you will find it most useful to think of emacs editing mode as a simplified emacs with a single, one-line window. All of the basic commands are available for cursor motion, cut-and-paste, and search.

emacs-mode uses control keys for the most basic editing functions. If you aren't familiar with emacs, you can think of these as extensions of the rudimentary "erase" character (usually BACKSPACE or DEL) that UNIX provides through its interface to users' terminals. For the sake of consistency, we'll assume your erase character is DEL from now on; if it is CTRL-H or something else, you will need to make a mental substitution.

The basic commands are really all you need to get around a command line, but a set of more advanced commands lets you do it with fewer keystrokes. These commands operate on words rather than single characters; emacs-mode defines a word as a sequence of one or more alphanumeric characters(i.e _ is not an alfanumeric character).
You will notice that the command ESC X, where X is any letter, often does for a word what CTRL-X does for a single character.
"Kill" is another word for "delete"; it is the standard term used in the readline library documentation for an "undoable" deletion.
 "yank" command will undelete a word if the word was the last thing deleted

A few commands deal with the entire line; Remember that CTRL-Y will always undelete the last thing deleted; if you use CTRL-K, that could be quite a few characters.

emacs-mode has several commands for recall previous commands by accessing the history list.  If you have cursor motion keys (arrow keys) you can use them instead. The up-arrow is the same as CTRL-P and the down-arrow is the same as CTRL-N. We'll stick to using the control keys because they can be used on all keyboards.

 A handy trick to save typing if you have already done a search is to type CTRL-R twice in a row. This recalls the previous search string you typed in.
That's  not available in versions of bash prior to 2.05a.
Textual Completion
One of the most powerful (and typically underused) features of emacs-mode is its textual completion facility, inspired by similar features in the full emacs editor, the C shell, and (originally) the old DEC TOPS-20 operating system.

The premise behind textual completion is simple: you should have to type only as much of a filename, user name, function, etc., to identify it unambiguously. This is an excellent feature; there is an analogous one in vi-mode. There are three commands in emacs-mode that relate to textual completion. The most important is TAB.
emacs users will recognize this as minibuffer completion.
When you type in a word of text followed by TAB, bash will attempt to complete the name. Then one of four things can happen:
  1. If there is nothing whose name begins with the word, the shell will beep and nothing further will happen.
  2. If there is a command name in the search path, a function name, or a filename that the string uniquely matches, the shell will type the rest of it, followed by a space in case you want to type in more command arguments. Command name completion is only attempted when the word is in a command position (e.g., at the start of a line).
  3. If there is a directory that the string uniquely matches, the shell will complete the filename, followed by a slash.
  4. If there is more than one way to complete the name, the shell will complete out to the longest common prefix among the available choices. Commands in the search path and functions take precedence over filenames.
A related command is ESC-?, which expands the prefix to all possible choices, listing them to standard output. Be aware that the completion mechanism doesn't necessarily expand to a filename. If there are functions and commands that satisfy the string you provide, the shell expands those first and ignores any files in the current directory. As we'll see, you can force completion to a particular type.

It is also possible to complete other environment entities.
  1. If the text being completed is preceded by a dollar sign ($), the shell attempts to expand the name to that of a shell variable
  2. If the text is preceded by a tilde (~), completion to a username(/home) is attempted
  3. if preceded by an at sign (@), a hostname is attempted
  4. ...look at table
If you find that you are interested only in completing long filenames, you are probably better off using ESC-/ rather than TAB. This ensures that the result will be a filename and not a function or command name.

Miscellaneous Commands
BSD-derived systems use CTRL-V and CTRL-W as default settings for the "quote next character" and "word erase" terminal interface functions, respectively.
A few of these miscellaneous commands are worth discussing, even though they may not be among the most useful emacs-mode commands.
  • CTRL-O is useful for repeating a sequence of commands you have already entered. Just go back to the first command in the sequence and press CTRL-O instead of RETURN. This will execute the command and bring up the next command in the history list. Press CTRL-O again to enter this command and bring up the next one. Repeat this until you see the last command in the sequence; then just hit RETURN.
  • Of the case-changing commands, ESC-L is useful when you hit the CAPS LOCK key by accident and don't notice it immediately. 
  • Since all-caps words aren't used too often in the UNIX world, you probably won't use ESC-U very often. 
  • CTRL-V will cause the next character you type to appear in the command line as is; i.e., if it is an editing command (or an otherwise special character like CTRL-D), it will be stripped of its special meaning. 
  • If it seems like there are too many synonyms for RETURN, bear in mind that CTRL-M is actually the same (ASCII) character as RETURN, and that CTRL-J is actually the same as LINEFEED, which UNIX usually accepts in lieu of RETURN anyway. 
  • ESC-. and ESC-_ are useful if you want to run several commands on a given file. The usual UNIX convention is that a filename is the last argument to a command. Therefore you can save typing by just entering each command followed by SPACE and then typing ESC-. or ESC-_. 

For example, say you want to examine a file using more, so you type:
   $ more myfilewithaverylongname
Then you decide you want to print it, so you type the print command lp. You can avoid typing the very long name by typing lp followed by a space and then ESC-. or ESC-_; bash will insert myfilewithaverylongname for you.


If you use emacs-mode and you aren't familiar with the full emacs, here is a subset that is easy to learn yet enables you to do just about anything:
  1. CTRL-A (and CTRL-E) move to beginning (and end) of line.
  2. CTRL-F (and CTRL-B) move forward (and backward) one character. In emacs-mode, the point (sometimes also called dot) is an imaginary place just to the left of the character the cursor is on. In the command descriptions, some say "forward" while others say "backward." Think of forward as "to the right of point" and backward as "to the left of point." You can also use the left and right cursor motion keys ("arrow" keys), but know that the control keys, work on all keyboards.
  3. DEL, CTRL-H (and CTRL-D) Delete one character backward (and  forward. Important: remember that typing CTRL-D when your command line is empty may log you off!) as with CTRL-F and CTRL-B, hold down to repeat if necessary. 
  4. Use CTRL-K to erase the entire line.
  5. Use CTRL-P and CTRL-N (or the up and down arrow keys) to move through the command history.
  6. Use CTRL-R to search for a command you need to run again. The shell dynamically searches back through the command history each time you type a letter, looking for the current substring in the previous commands. If the shell doesn't find the substring, it will beep.
  7. Use TAB for filename completion.

The fc Command
fc (fix command) is a built-in shell command that provides a superset of the C shell history mechanism. You can use it to:
  1. examine the most recent commands you entered, 
  2. to edit one or more commands with your favorite "real" editor, and 
  3. to run old commands with changes without having to type the entire command in again.
The -l option to fc lists previous commands. It takes arguments that refer to commands in the history list.
Arguments can be numbers or alphanumeric strings; numbers refer to the commands in the history list, while strings refer to the most recent command beginning with the string. 
 fc treats arguments in a rather complex way:
  1. If you give two arguments, they serve as the first and last commands to be shown.
  2. If you specify one number argument, only the command with that number is shown.
  3. With a single string argument, it searches for the most recent command starting with that string and shows you everything from that command to the most recent command.
  4. If you specify no arguments, you will see the last 16 commands you entered. bash also has a built-in command for displaying the history: history.
A few examples should make these options clearer.
If you type fc -l with no arguments, you will see a list of previous commands:
$ fc -l
492  ps
493  jobs
494  echo 2 * 3 > 5 is a valid inequality.
495  stty
496  stty -a
497  {2..5}
498  echo $RANDOM  

option, -n, suppresses the line numbers.
$ fc -ln
  jobs
  echo 2 * 3 > 5 is a valid inequality.
  stty
  stty -a
  {2..5}
  echo $RANDOM 


If you want to see only commands 492 through 494, type:
$ fc -l 492 494
492  ps
493  jobs
494  echo 2 * 3 > 5 is a valid inequality.

If you want to see only the jobs command, type:
$ fc -l 493

To see everything from the stty command up to the present, type:
$ fc -l stty

Finally, if you want to see commands between ps and echo, you can type;
fc -l p e, fc -l m 494, fc -l 492 494, etc.

The other important option (if you aren't a  vi or emacs user) to fc is -e "edit":
$ fc -e  /usr/bin/geany

You can specify the pathname of your favorite editor and edit typos in your previous command; then when you have made the changes, the shell will actually execute the new lines.

This seems like a lot of work just to fix a typo in your previous command; fortunately, there is a better way. You can set the environment variable FCEDIT to the pathname of the editor you want fc to use. If you put a line in your .bash_profile or environment file saying:
FCEDIT=/usr/bin/jed
you will get jed when you invoke fc.
If FCEDIT isn't set, then bash uses whatever the variable EDITOR is set to. If that's also not set, then bash defaults to vi.
fc is usually used to fix a recent command. When used without options, it handles arguments a bit differently than it does for the fc -l variation discussed earlier:
  1. With no arguments, fc loads the editor with the most recent command.
  2. With a numeric argument, fc loads the editor with the command with that number
  3. With a string argument, fc loads the most recent command starting with that string.
  4. With two arguments to fc, the arguments specify the beginning and end of a range of commands, as above.
Remember that fc actually runs the command(s) after you edit them. Therefore, the last-named choice can be dangerous. bash will attempt to execute all commands in the range you specify when you exit your editor. If you have typed in any multi-line constructs, the results could be even more dangerous. Although these might seem like valid ways of generating "instant shell programs," a far better strategy would be to direct the output of fc -ln with the same arguments to a file; then edit that file and execute the commands when you're satisfied with them:
$ fc -l cp > lastcommands; vi lastcommands; source lastcommands

In this case, the shell will not try to execute the file when you leave the editor!

There is one final option with fc. fc -s allows you to rerun a command. With an argument, fc will rerun the last command starting with the given string. Without an argument, it will rerun the previous command. The -s option also allows you to provide a pattern and replacement. For example, if you typed:

$ cs prog.c

You could correct it with fc -s cs=cc. This can be combined with the string search: fc -s cs=cc cs. The last occurence of cs will be found and replaced with cc.

(C shell's) History Expansion mechanism
History expansion is a primitive way to recall and edit commands in the history list. The way to recall commands is by the use of event designators.
  1. By far the most useful command is !!. Typing !! on the command line re-executes the last command. 
  2. If you know the command number of a specific command, you can use the !n form, where n is the command number. Command numbers can be determined from the history command. Alternatively, you can re-execute the most recent command beginning with the specified string by using !string.
  3. You might also find the last expansion in the table to be of some use if you've made a typing mistake. 
It's also possible to refer to certain words in a previous command by the use of a word designator. Table 2-16 lists available designators.
Note that when counting words, bash (like most UNIX programs) starts counting with zero, not with one.
The word designator follows the event designator, separated by a colon. You could, for example, repeat the previous command with different arguments by typing !!:0 followed by the new arguments.

Event designators may also be followed by modifiers. The modifiers follow the word designator, if there is one. Table 2-17 lists the available modifiers.
More than one modifier may be used with an event designator; each one is separated by a colon.

History expansion is fine for re-executing a command quickly, but it has been superseded by the command-line editing facilities that we looked at earlier. Its inclusion is really only for completeness, and we feel you are better off mastering the techniques offered in the vi or emacs editing modes.

vi Editing Mode
Like emacs-mode, vi-mode essentially creates a one-line editing window into the history list.
vi-mode is popular because vi is the most standard UNIX editor. 
But the function for which vi was designed, writing C programs, has different editing requirements from those of command interpreters. As a result, although it is possible to do complex things in vi with relatively few keystrokes, the relatively simple things you need to do in bash sometimes take too many keystrokes.

Like vi, vi-mode has two modes of its own: input and control mode. The former is for typing commands (as in normal bash use); the latter is for moving around the command line and the history list. When you are in input mode, you can type commands in and hit RETURN (RETURN works in both input and control modes, as does LINEFEED or CTRL-J) to run them.  In addition, you have minimal editing capabilities via control characters, which are summarized in Table 2-7

Note that at least some of these (depending on which version of UNIX you have. In particular, versions of UNIX derived from 4.x BSD have all of these commands built in) are the same as the editing commands provided by UNIX through its terminal interface.

  1. vi-mode will use your "erase" character as the "delete previous character" key; usually it is set to DEL or CTRL-H (BACKSPACE). 
  2. CTRL-V works the same way as in emacs-mode; it causes the next character to appear in the command line as is and lose its special meaning.
Under normal circumstances, you just stay in input mode. But if you want to go back and make changes to your command line, or if you want to recall previous commands, you need to go into control mode. To do this, hit ESC.

Simple Control Mode Commands
A full range of vi editing commands are available to you in control mode. The simplest of these move you around the command line and are summarized in Table 2-8.

vi-mode contains two "word" concepts.
  1. The simplest is any sequence of non-blank characters; we'll call this a non-blank word
  2. The other is any sequence of only alphanumeric characters (letters and digits) plus the underscore (_), or any sequence of only non-alphanumeric characters; we'll just call this a word.
Notice neither of these definitions is the same as the definition of a word in emacs-mode.
All of these commands except the last three can be preceded by a number that acts as a repeat count. Whenever you type a number for the repeat count, the number replaces the command prompt for the duration of the repeat command. If your keyboard has cursor motion keys ("arrow" keys), you can use the left and right arrows to move between characters instead of the h and l keys. Repeat counts will work with the cursor keys as well.
The last two will be familiar to users of UNIX utilities (such as grep) that use regular expressions, as well as to vi users.

Entering and Changing Text


Now that you know how to enter control mode and move around on the command line, you need to know how to get back into input mode so you can make changes and type in additional commands. A number of commands take you from control mode into input mode; they are listed in Table 2-9. All of them enter input mode a bit differently.

Most likely, you will use either i or a consistently, and you may use R occasionally (Why capital R instead of lowercase r? The latter is a slightly different command, which replaces only one character and does not enter input mode. With r, the next single character overwrites the character under the cursor. If you precede r with a number N, it will allow you to replace the next N existing characters on the line but still not enter input mode. Lowercase r is effective for fixing erroneous option letters, I/O redirection characters, punctuation, and so on). I and A are abbreviations for 0i and $a respectively.

Deletion Commands


The basic deletion command in vi-mode is d followed by one other letter. This letter determines what the unit and direction of deletion is, and it corresponds to a motion command, as listed previously in Table 2-8.
Table 2-10 shows some commonly used examples. These commands have a few variations and abbreviations. If you use a c instead of d, you will enter input mode after it does the deletion.


You can supply a numeric repeat count either before or after the d (or c). Table 2-11 lists the available abbreviations. Most people tend to use D to delete to end of line, dd to delete an entire line, and x (as "backspace") to delete single characters. If you aren't a hardcore vi user, you may find it difficult to make sure the more esoteric deletion commands are at your fingertips.

Every good editor provides "un-delete" commands as well as delete commands, and vi-mode is no exception. vi-mode maintains a delete buffer that stores all of the modifications to text on the current line only (note that this is different from the full vi editor). The command u undoes previous text modifications. If you type u, it will undo the last change. Typing it again will undo the change before that. When there are no more undo's, bash will beep. A related command is . (dot), which repeats the last text modification command.

There is also a way to save text in the delete buffer without having to delete it in the first place: just type in a delete command but use y ("yank") instead of d. This does not modify anything, but it allows you to retrieve the yanked text as many times as you like later on. The commands to retrieve yanked text are p, which inserts the text on the current line to the right of the cursor, and P, which inserts it to the left of the cursor.
The y, p, and P commands are powerful but far better suited to "real vi" tasks like making global changes to documents or programs than to shell commands, so we doubt you'll use them very often.
Moving Around in the History List
The next group of vi control mode commands we cover allows you to move around in and search your command history. This is the all-important functionality that lets you go back and fix an erroneous command without retyping the entire line. These commands are summarized in Table 2-12.

The first two can also be accomplished with the up and down cursor movement keys if your keyboard has them. The first three can be preceded by repeat counts (e.g., 3k or 3- moves back three lines in the command history).
If you aren't familiar with vi and its cultural history, you may be wondering at the wisdom of choosing such seemingly poor mnemonics as h, j, k, and l for backward character, forward line, backward line, and forward character, respectively. 
Well, there actually is a rationale for the choices other than that they are all together on the standard keyboard. Bill Joy originally developed vi to run on Lear-Siegler ADM-3a terminals, which were the first popular models with addressable cursors (meaning that a program could send an ADM-3a command to move the cursor to a specified location on the screen). The ADM-3a's h, j, k, and l keys had little arrows on them, so Joy decided to use those keys for appropriate commands in vi. Another (partial) rationale for the command choices is that CTRL-H is the traditional backspace key, and CTRL-J denotes linefeed.
Perhaps + and - are better mnemonics than j and k, but the latter have the advantage of being more easily accessible to touch typists. In either case, these are the most basic commands for moving around the history list.

Fans of vi and search utilities like grep should note that caret (^) for beginning-of-line is the only context operator vi-mode provides for search strings.

Character-Finding Commands
There are some additional motion commands in vi-mode, although they are less useful than the ones we saw earlier. These commands allow you to move to the position of a particular character in the line. They are summarized in Table 2-13, in which x denotes any character.

One final command rounds out the vi control mode commands for getting around on the current line: you can use the pipe character (|) to move to a specific column, whose number is given by a numeric prefix argument. Column counts start at 1; count only your input, not the space taken up by the prompt string. The default repeat count is 1, of course, which means that typing | by itself is equivalent to 0 (see Table 2-8).

Textual Completion
Although the character-finding commands and | are not particularly useful, vi-mode provides one additional feature that we think you will use quite often: textual completion.
This feature is not part of the real vi editor, and it was undoubtedly inspired by similar features in emacs and, originally, in the TOPS-20 operating system for DEC mainframes.
The rationale behind textual completion is simple: you should have to type only as much of a filename, user name, function, etc. as is necessary. Backslash (\) is the command that tells bash to do completion in vi-mode. If you type in a word, hit ESC to enter control mode, and then type \, one of four things will happen; they are the same as for TAB in emacs-mode

A related command is *. It behaves similarly to ESC-\, but if there is more than one completion possibility (number four in the previous list), it lists all of them and allows you to type further. Thus, it resembles the * shell wildcard character.

Less useful is the command =, which does the same kind of expansion as *, but in a different way. Instead of expanding the names onto the command line, it prints them, then gives you your shell prompt back and retypes whatever was on your command line before you typed =.

 It is also possible to expand other environment entities, as we saw in emacs-mode. If the text being expanded is preceded by a dollar sign ($), the shell will attempt to expand the name to that of a shell variable. If the text is preceded by a tilde (~), expansion to a username is attempted; if preceded by an at sign (@), a hostname.

Miscellaneous Commands
Several miscellaneous commands round out vi-mode; some of them are quite esoteric. The first of these can be preceded by a repeat count. A repeat count of n preceding the ~ changes the case of the next n characters. The cursor will advance accordingly.
A repeat count preceding _ causes the nth word in the previous command to be inserted in the current line; without the count, the last word is used. Omitting the repeat count is useful because a filename is usually the last thing on a UNIX command line, and because users often run several commands in a row on the same file. With this feature, you can type all of the commands (except the first) followed by ESC-_, and the shell will insert the filename.




readline
bash's command-line editing interface is readline. It is actually a library of software developed for the GNU project that can be used by applications requiring a text-based interface. It provides editing and text-manipulation features to make it easier for the user to enter and edit text. Just as importantly, it allows standardization, in terms of both key strokes and customization methods, across all applications that use it.

readline provides default editing in either of two modes: vi or emacs. Both modes provide a subset of the editing commands found in the full editors. We've already looked at the command sets of these modes in the previous sections. We'll now look at how you can make your own command sets.

readline gives bash added flexibility compared to other shells because it can be customized through the use of key bindings, either from the command line or in a special startup file. You can also set readline variables. We'll see how you can set up readline using your own startup file now, and then go on to examine how the binding capability can be used from the command line.


The readline Startup File
The default startup file is called .inputrc and must exist in your home directory if you wish to customize readline. You can change the default filename by setting the environment variable INPUTRC.

When bash starts up, it reads the startup file (if there is one) and any settings there come into effect. The startup file is just a sequence of lines that bind a keyname to a macro or readline function name. You can also place comments in the file by preceding any line with a #.
You can use either an English name or a key escape sequence for the keyname. For example, to bind CTRL-T to the movement command for moving to the end of the current line, you could place in your .inputrc:
     Control-t: end-of-line  

If you wanted to use a key escape sequence you could have put
"\C-t<">: end-of-line.

The \C- is the escape sequence prefix for Control. The advantage of the key sequence is that you can specify a sequence of keys for an action. In our example, once readline has read this line, typing a CTRL-T will cause the cursor to move to the end of the line.

The end-of-line in the previous example is a readline function. There are over 60 functions that allow you to control everything from cursor motions to changing text and command completion (for a complete list, see the bash manual page). All of the emacs and vi editing mode commands that we looked at have associated functions. This allows you to customize the default modes or make up completely new ones using your own key sequences.

Besides the readline functions, you can also bind a macro to a key sequence.
A macro is simply a sequence of keystrokes inside single or double quotes. 
Typing the key sequence causes the keys in the macro to be entered as though you had typed them. For example, we could bind some text to CTRL-T; "\C-t<">: <">Curiouser and curiouser!<">. Hitting CTRL-T would cause the phrase Curiouser and curiouser! to appear on the command line.

If you want to use single or double quotes in your macros or key sequence, you can escape them by using a backslash (\). Table 2-18 lists the common escape sequences.

readline also allows simple conditionals in the .inputrc. There are three directives: $if, $else, and $endif. The conditional of the $if can be an editing mode, a terminal type, or an application-specific condition.
To test for an editing mode, you can use the form mode= and test for either vi or emacs. For instance, to set up readline so that setting CTRL-T will take place only in emacs mode, you could put the following in your .inputrc:

$if mode=emacs
   "\C-t": "Curiouser and curiouser!"
$endif

Likewise, to test for a terminal type, you can use the form term=. You must provide the full terminal name on the right-hand side of the test. This is useful when you need a terminal-specific key binding. You may, for instance, want to bind the function keys of a particular terminal type to key sequences.
If you have other applications that use readline, you might like to keep your bash-specific bindings separate. You can do this with the last of the conditionals. Each application that uses readline sets its own variable, which you can test for. To test for bash specifics, you could put into your .inputrc:

$if bash

readline variables
readline has its own set of variables that you can set from within your .inputrc. Table 2-19 lists them.
The variables disable-completion, enable-keypad, input-meta, mark-directories, and visible-stats are not available in versions of bash prior to 2.0.
To set any of the variables, you can use the set command in your .inputrc. For example, to set vi-mode when you start up, you could place the line

set editing-mode vi

in your .inputrc. Every time bash starts it would change to vi-mode.


Key Bindings Using bind 
If you want to try out key bindings or you want to see what the current settings are, you can do it from the bash command line by using the bind command. The binding syntax is the same as that of the .inputrc file, but you have to surround each binding in quotes so that it is taken as one argument.

To bind a string to CTRL-T, we could type:

bind `"\C-t<">: <">Curiouser and curiouser!"'

This would bind the given string to CTRL-T just as in the .inputrc, except that the binding will apply only to the current shell and will cease once you log out.
bind also allows you to print out the bindings currently in effect by typing

bind -P
Versions of bash prior to 2.0 use -d instead of -p, and -v instead of -P. Also, the -r, -V, -S, -s, -u, and the new -v and -x options are not available in these older versions.
If you do so, you'll see things like:

abort can be found on "\C-g", "\C-x\C-g", "\e\C-g".
accept-line can be found on "\C-j", "\C-m".
alias-expand-line is not bound to any keys
arrow-key-prefix is not bound to any keys
backward-char can be found on "\C-b", "\eOD", "\e[D".
...

  • If you just want to see the names of the readline functions, you can use bind -l 
  • You can also unbind a function by using bind -u along with the name of the function; all keys for that function will then be unbound. 
  • Unbinding a key sequence can be done with bind -r followed by the sequence. 
  • bind -x is useful if you want to bind a shell command to a key sequence. For example, bind -x `"\C-l":ls' binds CTRL-L to the ls command. Hitting CTRL-L would then give a directory listing. 
  • Another option you might find useful is -p. This prints out the bindings to standard output in a format that can be re-read by bind, or used as a .inputrc file. So, to create a complete .inputrc file that you can then edit, you could type bind -p > .inputrc
  • To read the file back in again you can use another option, -f. This option takes a filename as its argument and reads the key bindings from that file. You can also use it to update the key bindings if you've just modified your .inputrc


Customizing your shell environment

You can change your environment trough
  • special files, 
  • Aliases,  
  • Options, 
  • Variables

Special files are:
  1.  .bash_profile(.bash_login, .profile)  : read by bash when you log in
  2.  .bash_logout   : read by bash when you log out
  3.  .bashrc           : read by bash when you start a new shell
Aliases are synonyms for commands or command strings that you can define for convenience.

Options controls for various aspects of your environment that you can turn on and off.

Variables are changeable values that are referred to by a name. The shell and other programs can modify their behavior according to the values stored in the variables.

All that are also the features that are common to the various shells available on UNIX.


Special files
These files may already exist in your home directory, depending on how your system administrator has set up your account. If they don't exist, your account is using only the default system file /etc/profile. You can easily create your own bash files using your favorite text editor.

If you examine your .bash_profile you will probably see lines similar to:
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
SHELL=/bin/bash
MANPATH=/usr/man:/usr/X11/man
EDITOR=/usr/bin/vi
   
PS1='\h:\w\$ '
PS2='> '
export EDITOR
These lines define the basic environment for your login account. When editing your .bash_profile, just add your new lines after the existing ones.
Note that whatever you add to your .bash_profile won't take effect until the file is re-read by logging out and then logging in again. Alternatively, you can also use the source command(or the synonymous command dot (.) ); source executes the commands in the specified file.
$ source .bash_profile

bash allows two synonyms for .bash_profile:
  1. .bash_login, derived from the C shell's file named .login, and 
  2. .profile, derived from the Bourne shell and Korn shell files named .profile.
Only one of these three is read when you log in. If .bash_profile doesn't exist in your home directory, then bash will look for .bash_login. If that doesn't exist it will look for .profile.

One advantage of bash's ability to look for either synonym is that you can retain your .profile if you have been using the Bourne shell. If you need to add bash-specific commands, you can put them in .bash_profile followed by the command source .profile.
When you log in, all the bash-specific commands will be executed, and bash will source .profile, executing the remaining commands. If you decide to switch to using the Bourne shell you don't have to modify your existing files.

A similar approach was intended for .bash_login and the C shell .login, but due to differences in the basic syntax of the shells, this is not a good idea.

 .bash_profile is read and executed only by the login shell. If you start up a new shell (a subshell) by typing bash on the command line, it will attempt to read commands from the file .bashrc. This scheme allows you the flexibility to separate startup commands needed at login time from those you might need when you run a subshell. If you need to have the same commands run regardless of whether it is a login shell or a subshell, you can just use the source command from within .bash_profile to execute .bashrc. If .bashrc doesn't exist then no commands are executed when you start up a subshell.

The file .bash_logout is read and executed every time a login shell exits. It is provided to round out the capabilities for customizing your environment. If you wanted to execute some commands that remove temporary files from your account or record how much time you have spent logged in to the system then you would place the commands in .bash_logout. This file doesn't have to exist in your account if it isn't there when you log out, then no extra commands are executed.


Aliases
Aliases are very handy for creating a comfortable environment, but they have essentially been superseded by shell scripts and functions. These give you everything aliases do plus much more, so if you become proficient at them, you may find that you don't need aliases anymore. However, aliases are ideal for novices who find UNIX to be a rather forbidding place, full of terseness and devoid of good mnemonics.

Alias let you rename the commands or allowed you to type in something simple instead of half a dozen options.
C shell users should note that the bash alias feature does not support arguments in alias expansions, as C shell aliases do. This functionality is provided by functions
Aliases can be defined:
  1. on the command line, 
  2. in your .bash_profile, or 
  3. in your .bashrc
Alias syntax:

alias name=command

This syntax specifies that name is an alias for command. Whenever you type name as a command, bash will substitute command in its place when it executes the line.
Notice that there are no spaces on either side of the equal sign (=); this is the required syntax.
There are a few basic ways to use an alias. The first, and simplest, is as a more mnemonic name for an existing command. Many commonly used UNIX commands have names that are poor mnemonics (grep, the UNIX file-searching utility, was named as an acronym for something like "Generalized Regular Expression Parser")and are therefore excellent candidates for aliasing, the classic example being:

alias search=grep

If you have to find Fred in a file phonelist and you have the word search defined as an alias for grep, you can type:
$ search Fred phonelist

Some people who aren't particularly good typists like to use aliases for typographical errors they make often. For example:

alias emcas=emacs
alias mali=mail
alias gerp=grep

Another common way to use an alias is as a shorthand for a longer command string.

alias cdvoy='cd sipp/demo/animation/voyager'
alias lf='ls -F'
Notice the quotes around the full cd command; these are necessary if the string being aliased consists of more than one word (with C shell aliases, in which the quotes aren't required).
few rules about aliasing
  1. bash makes a textual substitution of the alias for that which it is aliasing;
  2. Any special characters (such as wildcards like * and ?) that result when the alias is expanded are interpreted properly by the shell. So wildcards and other special characters cannot be used in the names of aliases, i.e., on the left side of the equal sign.
  3. aliases are recursive, which means that it is possible to alias an alias(i.e. the first alias is too long and doesn't save enough typing and we want to keep this alias but add a shorter abbreviation). Bash avoid infinite loop because only the first word of the replacement text is checked for further aliasing; if that word is identical to the alias being expanded, it is not expanded a second time.
  4. Aliases can be used only for the beginning of a command string(i.e. If alias anim=sipp/demo/animation/voyager then cd anim get an error "anim: No such file or directory"). An obscure feature of bash's alias facility (not present in the analogous C shell feature) provides a way around this problem. If the value of an alias (the right side of the equal sign) ends in a blank (To make the value of an alias end in a blank, you need to surround it with quotes i.e. alias cd='cd '), then bash tries to do alias substitution on the next word on the command line
  5. If you type alias name without an equal sign (=) and value, the shell will print the alias's value or alias name not found if it is undefined. 
  6. If you type alias without any arguments, you get a list of all the aliases you have defined.
  7. The command unalias name removes any alias definition for its argument.
 Another way to define a directory variable for use with the cd command is to use the environment variable cdable_vars


Options
A shell option is a setting that is either "on" or "off." While several options relate to arcane shell features that are of interest only to programmers, those that we will cover here are of interest to all users.
Table 3-1 lists the options that are useful to general UNIX users. All of them are off by default except as noted.




The basic commands that relate to options are:
  1. set -o optionname : the - turns the named option on. Most options also have one-letter abbreviations that can be used in lieu of the set -o command; These abbreviations are carryovers from the Bourne shell. Like several other "extra" bash features, they exist to ensure upward compatibility; otherwise, their use is not encouraged.
  2. set +o optionname : the + turns the named option off
The use of plus (+) and minus (-) signs is counterintuitive. The reason for this incongruity is that the dash (-) is the conventional UNIX way of specifying options to a command, while the use of + is an afterthought.


shopt
bash 2.0 introduced a new built-in for configuring shell behaviour, shopt. This built-in is meant as a replacement for option configuration originally done through environment variables and the set command.

the shopt -o functionality is a duplication of parts of the set command and is provided for completeness on the part of shopt, while retaining backward compatibility by its continued inclusion in set.
The format for this command is

shopt options option-names

The default action is to unset (turn off) the named options. If no options and arguments are given, or the -p option is used, shopt displays a list of the settable options and the values that they currently have. If -s or -u is also given, the list is confined to only those options that are set or unset, respectively.
A list of the most useful option names is given in Table 3-3.


Shell Variables
Shell variables can specify everything from your prompt string to how often the shell checks for new mail.Like an alias, a shell variable is a name that has a value associated with it. bash keeps track of several built-in shell variables; shell programmers can add their own. By convention, built-in variables should have names in all capital letters. bash does, however, have two exceptions (Versions prior to 2.0 have many more lowercase built-in variables. Most of these are now obsolete, the functionality having been moved to the shopt command.)

varname=value

There must be no space on either side of the equal sign, and if the value is more than one word, it must be surrounded by quotes. To use the value of a variable in a command, precede its name by a dollar sign ($).

You can delete a variable(Normally this isn't useful, since all variables that don't exist are assumed to be null, i.e., equal to the empty string "". But if you use the set option nounset, which causes the shell to indicate an error when it encounters an undefined variable, then you may be interested in unset) with the command:

unset varname

The easiest way to check a variable's value is to use the echo built-in command. All echo does is print its arguments, but not until the shell has evaluated them. This includes among other things taking the values of variables and expanding filename wildcards.
$ echo "$shell_variable"

If the variable is undefined, the shell will print a blank line. A more verbose way to do this is:
$ echo "The value of \$ varname  is \"$ varname \"." 

The first dollar sign and the inner double quotes are backslash-escaped (i.e., preceded with \ so the shell doesn't try to interpret them.


Variables and Quoting
Notice that we used double quotes around variables (and strings containing them) in these echo examples.
We know that some special characters inside double quotes are still interpreted, while none are interpreted inside single quotes.
A special character that "survives" double quotes is the dollar sign meaning that variables are evaluated. It's possible to do without the double quotes in some cases; for example, we could have written the above echo command this way:
$ echo The value of \$ varname  is \"$ varname \". 

But double quotes are more generally correct. Here's why. Suppose
harrykar@harrysas:~$ fred='Four    spaces    between     these     words.'
harrykar@harrysas:~$ echo $fred
Four spaces between these words.
harrykar@harrysas:~$ echo "$fred"
Four    spaces    between     these     words.

What happened to the extra spaces? Without the double quotes, the shell splits the string into words after substituting the variable's value, as it normally does when it processes command lines. The double quotes circumvent this part of the process (by making the shell think that the whole quoted string is a single word).
The distinction between single and double quotes becomes particularly important when we start dealing with variables that contain user or file input.

Rule of thumb
When in doubt, use single quotes...unless a string contains a variable, in which case you should use double quotes.





    Resources

    THE Unix SHELL GUIDE Bash Reference Manual
    GNU Readline Library
    Rute User's Tutorial and Exposition
    Introduction to Bash Scripting
    Advanced Bash Scripting Guide
    (pd)ksh
    (t)csh
    zsh

    Learning the bash Shell, 3rd Edition
    By Cameron Newham
    O'Reilly ISBN: 0-596-00965-8

    Ultimate Bashrc File

      No comments:

      Post a Comment