Invoking bash
Typically, the shells are invoked when you log in. The last thing the login program does is look in your /etc/passwd file to see what shell your system administrator has specified for you to use. If it isn't bash, you can either edit the /etc/passwd file, use the usermod command to change your login shell, or invoke bash from another shell by typing /bin/bash at the command line. The following options apply:
-norc | Don't read the "~/.bashrc" initialization file in an interactive shell. |
-rcfileFILENAME | Execute commands from the specified file rather than ~/.bashrc in an interactive shell. |
-noprofile | Don't load the system-wide startup file /etc/profile or any of the personal initialization files (~/.bash_profile, ~/.bash_login, ~/.profile). |
-version | Display version information. |
-login | Make this shell act as if it were directly invoked from login. |
-nobraceexpansion | Do not perform curly brace expansion. |
-nolineediting | Do not use the GNU Readline library to read interactive command lines. |
-posix | Force bash to conform to the Posiz 1003.2 standard. |
-c STRING | Read and execute commands from STRING after processing the options and then exit. |
-i | Force the shell to run interactively. |
Startup Files
When you log in or otherwise invoke bash, the shell looks at a variety of files and attempts to execute any shell commands contained therein, a process known as sourcing. These files are where you set any configuration information (e.g., environment variables, aliases) or execute startup programs and scripts (fortune, startx).
Example: To set the environment variable PATH to include the directory /sbin, include the following line in your ~/.bash_profile file:
PATH=$PATH:/sbin
This sets the new value of PATH to be equal to the old value ($PATH) plus the directory /sbin.
Bash may be invoked interactively either at login time or from another shell, or non-interactively. Which files it attempts to source depend on how it was called.
Interactive bash
At login: If the shell is being run as a normal, interactive shell, bash executes startup files at login time. Assuming the shell was invoked without the -noprofile option, files are sourced under the following circumstances:
1. If /etc/profile exists, then source it.
2. If ~/.bash_profile exists, then source it, else if ~/.bash_login exists, then source it, else if ~/.profile exists, then source it.
At logout: If ~/.bash_logout exists, source it.
Nonlogin Interactive bash
For nonlogin interactive shells (subject to the -norc and -rcfile options):
Startup Time: If ~/.bashrc exists, then source it.
Non-interactive Shells
Startup Time: If the environment variable ENV is non-null, expand the variable and source the file named by the value. If bash is not started in Posix mode, it looks for BASH_ENV before ENV.
So, typically, your ~/.bash_profile contains the line
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
In non-interactive instances of bash, the $PS1 variable is unset. |
Aliases
Aliases are a shell mechanism that enables you to create shortened versions of common commands. You create an alias by typing the word "alias", the character sequence you want to be your new alias, an equal sign, and the value the alias expands to.
Example: These are two of my favorite aliases:
alias l='ls -a --color'
alias ll='ls -al --color'
Create a file in your home directory called .alias and source it in one of your startup scripts. The .alias file is just a plain ASCII text file containing a list of your favorite aliases, exactly as you would type them on the command line. To source the alias file you might include the following line in the ~/.bashrc file: |
. ./.alias
This will give you back all your favorite aliases at login time and provide a central location for storing and referencing your aliases.
alias
[NAME[=VALUE] ]
Without arguments, print the current list of aliases. Otherwise, define an alias. When the NAME is typed, bash will expand the name into VALUE and run VALUE as the command.
unalias
[-a] [NAME ]
Remove the specified NAME from the list of aliases. If -a is supplied, all aliases are removed.
Command History
As I mentioned in the introduction, bash stores commands in a history file ($HISTFILE) as you type them. Those commands are, of course, accessible at a later time. The following key combinations allow you to do various stuff with your command history:
<Enter> | Accept the line regardless of where the cursor is. |
<Ctrl >-P | Move "up" through the history list. |
<Ctrl>-n | Move "down" through the history list. |
<Meta>-< | Move to the first line in the history. |
<Meta>-> | Move to the end of the input history. |
<Ctrl>-r | Search backward starting at the current line and moving "up" through the history as necessary. |
<Ctrl>-s | Search forward starting at the current line and moving "down" through the history as necessary. |
<Meta>-p | Search backward starting at the current line and moving "up" through the history as necessary using a non-incremental search for a string supplied by the user. |
<Meta>-n | Search forward starting at the current line and moving "down" through the history as necessary using a non-incremental search for a string supplied by the user. |
<Meta>-<Ctrl>-y | Yank nth argument of previous command. |
<Meta>-., M-_ | Insert last argument to the previous command. |
Alternatively, and (to my mind, at least) somewhat less conveniently, you have the ! (pronounced "bang" honest) method of accessing your history:
! | Start a history substitution, except when followed by a space, tab, the end of the line, = or (. |
!! | Refer to the previous command. This is a synonym for `!-1. |
!n | Refer to command line N. |
!-n | Refer to the command N lines back. |
!string | Refer to the most recent command starting with STRING. |
!?string[`?] | Refer to the most recent command containing STRING. |
!# | The entire command line typed so far. |
^string1^string2^ | Quick Substitution. Repeat the last command, replacing STRING1 with STRING2. Equivalent to "!!:s/string1 /string2/". |
In addition, you also have the history command, which will display a listing of your command history.
history
[N] [ [-w -r -a -n] [FILENAME]]
Display the history list with line numbers.
-w | Write out the current history to the history file. |
-r | Read the current history file and make its contents the history list. |
-a | Append the new history lines. |
-n | Read the history lines not already read from the history file into the current history list. |
Command Completion
One of the niftiest things about bash is that it will do a lot of your typing for you.
<Tab> | Attempt to do completion on the text before the cursor. |
<Meta>-? | List the possible completions of the text before the cursor. |
<Ctrl>-x, <Ctrl>-r | Read in the contents of your init file and incorporate any bindings or variable assignments found there. |
<Ctrl>-g | Abort the current editing command and ring the terminal's bell (subject to the setting of "bell-style"). |
<Esc> | Make the next character that you type be metafied. |
<Ctrl>-_, <Ctrl>-x, <Ctrl>-u | Incremental undo, separately remembered for each line. |
<Meta>-r | Undo all changes made to this line. |
Command Line Editing
Bash provides a slightly bewildering array of control characters for command line editing. These are most of them.
Handling Characters
<Ctrl>-b | Move back one character. |
<Ctrl>-f | Move forward one character. |
<Del> | Delete the character to the left of the cursor. |
<Ctrl>-d | Delete the character underneath the cursor. |
Printing characters | Insert the character into the line at the cursor. |
<Ctrl>-u | Undo the last thing that you did. You can undo all the way back to an empty line. |
Moving Around on the Line
<Ctrl>-a | Move to the start of the line. |
<Ctrl>-e | Move to the end of the line. |
<Meta>-f | Move forward a word.<Anchor2> |
<Meta>-b | Move backward a word. |
<Ctrl>-l | Clear the screen, reprinting the current line at the top. |
<Ctrl>-k | Kill the text from the current cursor position to the end of the line. |
<Meta>-d | Kill from the cursor to the end of the current word, or, if between words, to the end of the next word. |
<Meta>-DEL | Kill from the cursor the start of the previous word, or, if between words, to the start of the previous word. |
<Ctrl>-w | Kill from the cursor to the previous whitespace. This is different from M-DEL because the word boundaries differ. |
<Ctrl>-y | Yank the most recently killed text back into the buffer at the cursor.9 |
<Meta>-y | Rotate the kill-ring, and yank the new top. You can do this only if the prior command is <Ctrl>-y or M-y. |
Changing Text
<Ctrl>-d | Delete the character under the cursor. |
<Ctrl>-q, C-v | Add the next character that you type to the line verbatim. |
<Meta>-<Tab> | Insert a tab character. |
<Ctrl>-t | Drag the character before the cursor forward over the character at the cursor, moving the cursor forward as well. |
<Meta>-t | Drag the word behind the cursor, past the word in front of the cursor, moving the cursor over that word as well. |
<Meta>-u | Uppercase the current (or following) word. |
<Meta>-l | Lowercase the current (or following) word. |
<Meta>-c | Capitalize the current (or following) word. |
Killing and Yanking
<Ctrl>-k | Kill the text from the current cursor position to the end of the line. |
<Ctrl>-x | Kill backward to the beginning of the line. |
<Ctrl>-u | Kill backward from the cursor to the beginning of the current line. |
<Meta>-d | Kill from the cursor to the end of the current word, or, if between words, to the end of the next word. |
<Meta>-<Del> | Kill the word behind the cursor. |
<Ctrl>-w | Kill the word behind the cursor, using white space as a word boundary. |
<Ctrl>-y | Yank the top of the kill-ring into the buffer at the current cursor position. |
<Meta>-y | Rotate the kill-ring, and yank the new top. You can do this only if the prior command is yank or yank-pop. |
Key Bindings
<Ctrl>-a | Move to the start of the current line. |
<Ctrl>-e | Move to the end of the line. |
<Ctrl>-f | Move forward a character. |
<Ctrl>-b | Move back a character. |
<Meta>-f | Move forward to the end of the next word. |
<Meta>-b | Move back to the start of this, or the previous, word. |
<Ctrl>-l | Clear the screen and redraw the current line. |
Word Designators
Bash allows you to specify words within a command line. These operators are primarily intended for use in shell programming.
Word Designation Operators
These operators allow you to specify one or more words within a command line.
: | Separate the event specification from the word designator. |
0 (zero) | The zeroth word. Usually, the zeroth word is the command word. |
n | The nth word. |
^ | The first argument; that is, word 1. |
$ | The last argument. |
% | The word matched by the most recent "?string?" search. |
x-y | A range of words; "-Y" abbreviates "0-Y". |
* | All words except the zeroth. |
x* | Abbreviates "x-$". |
x- | Abbreviates "x-$" like "x*", but omits the last word. |
Modifiers
After the optional word designator, you can add a sequence of one or more of the following modifiers, each preceded by a colon (:):
h | Remove a trailing pathname component, leaving only the head. |
r | Remove a trailing suffix of the form .SUFFIX, leaving the basename. |
e | Remove all but the trailing suffix. |
t | Remove all leading pathname components, leaving the tail. |
p | Print the new command, but do not execute it. |
q | Quote the substituted words, escaping further substitutions. |
x | Quote the substituted words as with q. |
s/old/new/ | Substitute NEW for the first occurrence of OLD in the event line. |
& | Repeat the previous substitution. |
g | Apply change over entire event line. |
Shell Variables
Technically, the variables in this section include both shell variables and environments variables. Environment variables are a special subset of shell variables that are exported to all subprocesses of the shell. (See the export command.)
By convention, shell variables are usually composed of ALL CAPITAL LETTERS, but you do see lowercase shell variables in bash from time to time.
Shell variables are set with the equal sign (=). The syntax is variable=value.
Example: To set the value of the HISTFILE variable (where HISTFILE is the name of the file where your history commands are stored), use
HISTFILE=/home/shawkins/.bash_history
You may also want to export the variable. Exporting makes the value of the variable available to any subprocesses invoked by the shell.
Example: To set and export the value of the HISTFILE variable, enter
export HISTFILE=/home/shawkins/.bash_history
The current values of shell variables can be displayed with env or echo.
Example: To display the current values of all your environment variables, enter
env
To display the current value of a particular environment variable, use echo $<variable>. The $ tells the shell that you're referring to the value of the variable.
Example: To display the current value of your CDPATH, type:
echo $CDPATH
Shell variables are built-in variables used by the shell for uh various stuff. For example, the PATH variable is a list of directories, separated by a colon, through which the shell searches for the executable program corresponding to the command you typed in at the shell prompt.
If you're getting "command not found" errors for programs you know are out there, you probably need to modify your PATH. |
Bourne Shell Variables
BASH_VERSION | The version number of the current instance of bash. |
CDPATH | Colon-separated list of directories used as a search path for the cd command. |
EUID | The numeric effective user id of the current user. |
FIGNORE | A colon-separated list of suffixes to ignore when performing filename completion. |
HISTCMD | The history number of the current command. |
HISTCONTROL | Set to a value of "ignorespace", it means don't enter lines that begin with a space or tab into the history list. Set to a value of "ignoredups", it means don't enter lines that match the last entered line. A value of "ignoreboth" combines the two options. Unset or set to any other value saves all lines on the history list. |
HISTFILE | The file containing the command history. |
HISTFILESIZE | Number of commands to store in the history file. |
HOME | Home directory of current user. |
HOSTFILE | Contains the name of a file to be read when the shell needs to complete a hostname. |
HOSTTYPE | A string describing the machine Bash is running on. |
IFS | A list of characters that separate (delimit) fields; used when the shell splits words as part of expansion. |
IGNOREEOF | Number of consecutive EOF's Bash will read before exiting. |
INPUTRC | The name of the Readline startup file, overriding the default of ~/.inputrc. |
| Name of file to check for new mail. |
MAILCHECK | The number of seconds to wait before checking for new mail. |
MAILPATH | Colon-separated list of files that the shell periodically checks for new mail. |
nolinks | If present, do not follow symbolic links when doing commands that change the current working directory. |
OLDPWD | Previous working directory. |
OPTARG | Value of the last option argument processed by the getopts built in. |
OPTIND | Index of the last option processed by the getopts built in. |
OSTYPE | A string describing the operating system Bash is running on. |
PATH | Colon separated list of directories in which the shell looks for commands. |
PROMPT_COMMAND | If present, this contains a string command to execute before the printing of each primary prompt ("$PS1"). |
PS1 | The primary prompt string. |
PS2 | The secondary prompt string. |
PS3 | Used as the prompt for the select command. |
PS4 | Prompt printed before the command line is echoed when the -x option is set. |
PWD | Current working directory. |
RANDOM | Generate a random integer. |
REPLY | Default variable for the read bulletin. |
SECONDS | Number of seconds since the shell was started. |
TMOUT | Interpret the value as the number of seconds to wait for input after issuing the primary prompt. |
UID | The numeric real user id of the current user. |
Shell Prompt
Shell prompts range from the trivial (">") to the thoroughly overboard. (I once had a shell prompt so long I included a newline character in it so I'd have room to type commands.) My current prompt is somewhere in between. I set it with the command
PS1='\h:$PWD>'
in my .bashrc file to produce prompts like the following:
odin:/home/root>
Note the use of an environment variable ($PWD) within the prompt. The following table describes the special characters that can appear in the PS1 variable:
\t | The time, in HH:MM:SS format. |
\T | The time in 12-hour HH:MM:SS format. |
\@ | The time in 12-hour am/pm format. |
\d | The date, in "Weekday Month Date" format (e.g., "Tue May 26"). |
\e | ASCII escape character. |
\n | Newline. |
\s | The name of the shell. |
\w | The current working directory. |
\W | The basename of $PWD. |
\u | Your username. |
\h | The hostname. |
\# | The command number of this command. |
\! | The history number of this command. |
\nnn | The character corresponding to the octal number nnn. |
\$ | If the effective uid is 0, #; otherwise, $. |
\\ | A backslash. |
\[ | Begin a sequence of nonprinting characters. |
\] | End a sequence of nonprinting characters. |
Shell Arithmetic
As you might imagine, the shell has pretty much the full complement of arithmetic (including logic) operators. To specify an arithmetic expression, encase it in double parentheses.
Arithmetic Expansion
Arithmetic expansion allows the evaluation of an arithmetic expression and the substitution of the result. There are two formats for arithmetic expansion:
$[ expression ]
$(( expression ))
Example: The following expression adds the values of the variables A and B:
$((A + B))
Example: To print out the results of an arithmetic expression, use echo:
echo "A + B is $((A+B))"
Arithmetic Builtins
let
EXPRESSION
[EXPRESSION]
Perform arithmetic on shell variables.
Example: To assign the value of an arithmetic expression to another shell variable, use let:
let C=$((A+B))
Operators
- + | unary minus and plus |
! ~ | logical and bitwise negation |
* / % | multiplication, division, remainder |
+ - | addition, subtraction |
<< >> | left and right bitwise shifts |
<= >= < > | comparison |
== != | equality and inequality |
& | bitwise AND |
^ | bitwise exclusive OR |
| | bitwise OR |
&& | logical AND |
|| | logical OR |
= *= /= %= += -= <<= >>= &= ^= |=' | assignment |
Looping Statements
until
TEST-COMMANDS; do CONSEQUENT-COMMANDS; done Execute the CONSEQUENT-COMMANDS until the TEST-COMMANDS section has a nonzero exit status.
while
TEST-COMMANDS; do CONSEQUENT-COMMANDS; done Execute CONSEQUENT COMMANDS as long as the final command in TEST-COMMANDS has an exit status of zero.
for
NAME [in WORDS ]; do COMMANDS; done Execute COMMANDS for each member of the WORDS set with NAME bound to the current member.
Conditional Statements
Conditional statements are statements that affect the flow of the execution. The common characteristic is that they evaluate conditions present and may take action based on those conditions. The two most common are the if statement and the case statement:
if [CONDITION] then
STATEMENTS;
[elif CONDITION-JR then
STATEMENTS-JR;]
[else ALTERNATE STATEMENTS]
fi
This command executes the STATEMENTS if the final command in the CONDITION sequence has an exit status of zero.
If the exit status of the CONDITION is nonzero, the elifs are executed in turn, again evaluating the exit status of the final command and either executing the CONDITION-JR commands or not, depending on the exit status of STATEMENTS-JR.
If ALTERNATE-CONSEQUENTS exist and the final TEST-COMMAND has a nonzero exit status, the ALTERNATE-CONSEQUENTS are executed.
Example: To test whether the script file ~/startx exists (-e flag) and run it if it does, use
if [ -e ~/startx ]; then
.~/startx
fi
case WORD in [PATTERN [| PATTERN]...)
COMMANDS ;;]... esac
The case command is used to selectively execute commands. Conceptually, it's a lengthy if statement with a lot of conditions. If WORD matches PATTERN the COMMANDS associated with PATTERN are executed.
Example: To test the value of the first argument passed in and execute various scripts based on its value:
case $1 in
0 ) . script1;;
1 ) . script2;;
2 ) . script3;;
esac
The test command can also be used to evaluate common characteristics of
test
-[bcdfhLpSt] FILE
test
-[gkruwxOG] FILE
test
-e -s -nt -ot -ef FILE
test
EXPR
Evaluate the expression and return a status of 0 (true) or 1 (false), depending on the value of the expression. It can be used to test properties of files, to evaluate some properties of strings, and in numeric comparisons.
File Tests
-bFILE | Is file a block special device? |
-cFILE | Is file a character special device? |
-dFILE | Is file a directory? |
-eFILE | Does file exist? |
-fFILE | Is file a regular file? |
-GFILE | Are you and file in a common group? |
-HFILE | Is file a hard link? |
-LFILE | Is file a symbolic link? |
-OFILE | Do you own file? |
-pFILE | Is file a named pipe? |
-rFILE | Do you have read permission? |
-SFILE | Is file a socket? |
-t [FD] | Is file opened on a terminal? |
-wFILE | Do you have write permission? |
-xFILE | Do you have execute permission |
Access Permission Tests
All the Mtests in this section fail if the specified file does not exist. |
-gFILE | Is the set-group-id bit set? |
-kFILE | Is the sticky bit set? |
-rFILE | Is the file readable? |
-uFILE | Is the set-user-id bit set? |
-wFILE | Is the file writable? |
-xFILE | Is the file executable? |
-OFILE | Is the file owned by the current user? |
-GFILE | Is the file owned by the current group? |
File Characteristic Tests
-eFILE | Does the file exist? |
-sFILE | Is the file size greater than zero? |
FILE1-ntFILE2 | FILE1 is newer than FILE2? (T/F) |
FILE1-otFILE2 | FILE1 is older than FILE2? (T/F) |
FILE1-efFILE2 | True if FILE1 and FILE2 are hard linked (they have the same device and inode numbers). |
String Tests
-zSTRING | Is string zero length? |
-nSTRING | Is string nonzero length? |
STR1=STR2 | True if STR1 is the same as STR2. |
STR1 != STR2 | True if STR1 is not the same as STR2. |
Numeric Tests
All arguments must be numeric. |
ARG1-eqARG2 | ARG1 equal to ARG2. |
ARG1-neARG2 | True if ARG1 is not equal to ARG2. |
ARG1-ltARG2 | True if ARG1 is less than ARG2. |
ARG1-leARG2 | True if ARG1 is less than or equal to ARG2. |
ARG1-gtARG2 | True if ARG1 is greater than ARG2. |
ARG1-geARG2 | True if ARG1 is greater than or equal to ARG2. |
Logical Connectives
!EXPR | True if EXPR is false (Logical not). |
EXPR1-aEXPR2 | True if EXPR1 and EXPR2 are true (Logical and). |
EXPR1-oEXPR2 | True if at least one of EXPR1 and EXPR2 is true (Logical or). |
Shell Functions
Shell functions are a way to invoke a group of commands by typing a single name.
[`function'] NAME () { COMMAND-LIST;}
Example: The following function prints out the square of its argument:
function printsquare()
{
echo "The square of $1 is (($1*$1))";
}
Directory Manipulation
pushd
[DIR | +N | -N]
Save the current directory on a list and then "cd" to DIR. With no arguments, pushd exchanges the top two directories.
+N | Brings the nth directory (counting from the left of the list printed by "dirs") to the top of the list by rotating the stack. |
-N | Brings the nth directory (counting from the right of the list printed by "dirs") to the top of the list by rotating the stack. |
DIR | Makes the current working directory be the top of the stack, and then CDs to DIR. You can see the saved directory list with the "dirs" command. |
popd
[+N|-N]
Pop the directory stack and cd to the new top directory.
+N | Remove the nth directory (counting from the left of the list printed by "dirs"), starting with zero. |
-N | Removes the nth directory (counting from the right of the list printed by "dirs"), starting with zero. |
dirs
[+N | -N] [-L]
Display the list of currently remembered directories.
+N | Display the Nth directory (counting from the left of the list, starting with 0). |
-N | Display the Nth directory (counting from the right of the list, starting with 0). |
-L | Expand the ~. This is usually used to abbreviate the home directory into a full path in order to produce a longer listing. |
Shell Built-ins
The following commands are built into the bash shell and accessible via the command line or for use in scripting:
: | Expand arguments and perform redirections, but nothing else. |
. filename | Execute the shell commands contained in the specified filename. |
break | Exit from a for, while, or until loop. |
cd | Change the current working directory. |
continue | Resume the execution of the loop (for, while, or until) in which the continue command is contained at the next iteration. |
echo [arg,...] | Print to standard output the specified arguments separated by spaces. |
eval [arg,...] | Concatenate the arguments into a single command, read the result, and execute it. |
exec command | When an executable command is specified, it replaces the shell. When no command is specified, redirections may be used to affect the current shell environment. |
exit | Exit the shell. |
exportarg,... | Pass the arguments as variables to the child processes in the environment. |
getopts | Parse options to shell scripts or functions. |
hash | Remember the full pathnames of commands specified as arguments, so that they need not be searched for on subsequent invocations. |
killprocess | Send a signal to a process. |
pwd | Print the current working directory. |
readvar,... | Read a line from the shell input and use it to set the values of specified variables. |
readonly | Mark variables as unchangeable. |
return value | Exit shell function with specified value. |
shift | Shift positional parameters to the left. |
testexpr,[ | Evaluate the specified conditional expression. |
times | Print out the user and system times used by the shell and its children. |
trap | Specify commands to be executed when the shell receives signals. |
umask | Set the shell process's file creation mask. |
unset | Get rid of the specified shell variable. |
wait | Wait until child processes exit and report their exit status. |