With an interactive shell, the standard input, output, and error are tied to a terminal. When using the Bourne Again shell interactively, you will type Linux/Unix commands at the bash prompt and wait for a response. Bash provides you with a large assortment of built-in commands and command line shortcuts, such as history, aliases, file and command completion, command line editing, and many more. Some of the features were present in the standard UNIX Bourne shell but the Gnu project has expanded the shell to include a number of new features as well adding POSIX compliancy. With the release of bash 2.x, so many features of the UNIX Korn shell and C shell have been included that the bash shell is a fully functional shell at both the interactive and programming level, while upwardly compatible with the standard Bourne shell. For Linux and UNIX users, bash offers an alternative to the standard UNIX shells, sh, csh, and ksh.
This chapter focuses on how you interact with bash at the command line and how to customize your working environment. You will learn how to take advantage of all shortcuts and built-in features in order to create an efficient and fun working environment. The next chapter takes you a step further. Then you will be ready to write bash shell scripts to further tailor the working environment for yourself by automating everyday tasks and developing sophisticated scripts, and if you are an administrator, doing the same not only for yourself but also for whole groups of users.
The Bourne Again shell is a Capricorn, born on January 10, 1988, fathered by Brian Fox and later adopted by Chet Ramey, who now officially maintains bash, enhances it, and fixes bugs. The first version of bash was 0.99. The latest version (as of this writing) is version 2.03. Major enhancements were completed in version 2.0. There are a number of operating systems that are still using version 1.14.7 and all versions are freely available under the Gnu public license. To see what version you are using, use the -version option to bash or print the value of the BASH_VERSION environment variable.
$ bash -version GNU bash, version 2.03.0(1)-release (i686-pc-linux-gnu) Copyright 1998 Free Software Foundation, Inc. $ echo $BASH_VERSION 2.03.0(1)-release |
If the bash shell is your login shell, it follows a chain of processes before you see a shell prompt.[1]
[1] To get the latest version of bash, go to Web site: http://www.delorie.com/gnu/.
When the system boots, the first process to run is called init, PID #1. It spawns a getty process. This process opens up the terminal ports, providing a place where standard input comes from and a place where standard output and errors go, and puts a login prompt on your screen. The /bin/login program is then executed. The login program prompts for a password, encrypts and verifies the password, sets up an initial environment, and starts up the login shell, /bin/bash, the last entry in the passwd file. The bash process looks for the system file, /etc/profile, and executes its commands. It then looks in the user's home directory for an initialization file called .bash_profile. After executing commands from .bash_profile [2], it will execute a command from the user's ENV file, usually called .bashrc, and finally the default dollar sign ($) prompt appears on your screen and the shell waits for commands. (For more on initialization files, see "The Environment" on page 262.)
[2] There are a number of different initialization files used by bash; they are discussed on the next pages.
The chsh command allows you to change your login shell. For example, if you are currently using the standard Bourne shell and would rather have bash as your login shell, you can use chsh to change your login shell. If a shell is not given on the command line, chsh prompts for one. All valid shells are listed in the /etc/shells file. (See Table 8.1.)
Option | What It Does |
---|---|
-l,--list-shells | Prints the list of available shells listed in /etc/shells and exits |
-s, --shell | Specifies the login shell |
-u, --help | Prints a usage message and exits |
-v, --version | Prints version information and exits |
1 $ chsh -l /bin/bash /bin/sh /bin/ash /bin/bsh /bin/tcsh /bin/csh /bin/ksh /bin/zsh 2 $ chsh Changing shell for ellie. New shell [/bin/sh] tcsh chsh: shell must be a full pathname. |
Explanation
Lists all available shells on this Linux system.
Asks the user to type the full pathname for a new login shell. Fails unless a full pathname such as, /bin/tcsh, is given.
The environment of a process consists of variables, open files, the current working directory, functions, resource limits, signals, and so forth. It defines those features that are inherited from one shell to the next and the configuration for the working environment. The configuration for the user's shell is defined in the shell initialization files.
The bash shell has a number of startup files that are sourced. Sourcing a file causes all settings in the file to become part of the current shell; i.e., a subshell is not created. (The source command is discussed in "The source or dot Command" on page 281.) The initialization files are sourced depending on the whether the shell is a login shell, an interactive shell (but not the login shell), or a noninteractive shell (a shell script).
When you log on, before the shell prompt appears, the system-wide initialization file, etc/profile, is sourced. Next, if it exists, the .bash_profile in the user's home directory is sourced. It sets the user's aliases and functions and then sets user-specific environment variables and startup scripts.
If the user doesn't have a .bash_profile, but does have a file called .bash_login, that file will be sourced, and if he doesn't have a .bash_login, but does have a .profile, it will be sourced. (The .bash_login file is similar to the C shell's .login file and the .profile is normally sourced by the Bourne shell when it starts up.)
Here is a summary of the order that bash processes its initialization files (see Figure 8.2):[3]
[3] If the shell is invoked with the -noprofile option, none of the initialization files are read.
if /etc/profile exists, source it, if ~/.bash_profile exists, source it, if ~/.bashrc exists, source it, else if ~/.bash_login exists, source it, else if ~/.profile exists, source it.
The /etc/profile file is a system-wide initialization file set up by the system administrator to perform tasks when the user logs on. It is executed when the bash shell starts up. It is also available to all Bourne and Korn shell users on the system and normally performs such tasks as checking the mail spooler for new mail and displaying the message of the day from the /etc/motd file. (The following examples will make more sense after you have completed this chapter.)
(Sample /etc/profile)
# /etc/profile
# System wide environment and startup programs
# Functions and aliases go in /etc/bashrc
1 PATH="$PATH:/usr/X11R6/bin"
2 PS1="[u@h W]\$ "
3 ulimit -c 1000000
4 if [ `id -gn` = `id -un` -a `id -u` -gt 14 ]; then
5 umask 002
else
umask 022
fi
6 USER=`id -un`
7 LOGNAME=$USER
8 MAIL="/var/spool/mail/$USER"
9 HOSTNAME=`/bin/hostname`
10 HISTSIZE=1000
11 HISTFILESIZE=1000
12 export PATH PS1 HOSTNAME HISTSIZE HISTFILESIZE USER LOGNAME MAIL
13 for i in /etc/profile.d/*.sh ; do
14 if [ -x $i ]; then
15 . $i
fi
16 done
17 unset i #
|
Explanation
The PATH variable is assigned locations where the shell should search for commands.
The primary prompt is assigned. It will be displayed in the shell window as the user's name (u),the @ symbol, the host machine (W),and a dollar sign.
The ulimit command (a shell built-in command) is set to limit the maximum size of core files created to 1000000 bytes. Core files are memory dumps of programs that have crashed, and they take up a lot of disk space.
This line reads: if the user's group name is equal to the user's name and the user's id number is greater than 14... (see 5)
Then set the umask to 002. When directories are created they will get 775 permissions and files will get 664 permissions. Otherwise, the umask is set to 022, giving 755 to directories and 644 to files.
The USER variable is assigned the username (id -un).
The LOGNAME variable is set to the value in $USER.
The MAIL variable is assigned the path to the mail spooler where the user's mail is saved.
The HOSTNAME variable is assigned the name of the user's host machine.
The HISTSIZE variable is set to 1000. HISTSIZE controls the number of history items that are remembered (from the history list stored in the shell's memory) and saved in the history file after the shell exits.
The HISTFILESIZE is set to limit the number of commands stored in the history file to 1000, i.e., the history file is truncated after it reaches 1000 lines. (See "History" on page 292.)
These variables are exported so that they will be available in subshells and child processes.
Check to see if the file is executable, and if it is… (see 15)
Execute (source) the file with the dot command. The files in the /etc/profile.d directory: lang.sh and mc.sh, respectively, set the Linux character and font sets and create a function called mc that starts up a visual/browser file manager program, called Midnight Commander. To see how the file manager works, type mc at the bash prompt.
The done keyword marks the end of the for loop.
If the ~/.bash_profile is found in the user's home directory, it is sourced after the /etc/profile. If ~/.bash_profile doesn't exist, bash will look for another user-defined file, ~./bash_login, and source it, and if ~./bash_login doesn't exist, it will source the ~/.profile, if it exists. Only one of the three files (~/.bash_profile, ~/.bash_login, or ~/ .profile) will be sourced. Bash will also check to see if the user has a .bashrc file and then source it.
(Sample .bash_profile) # .bash_profile # The file is sourced by bash only when the user logs on. # Get the aliases and functions 1 if [ -f ~/.bashrc ]; then 2 . ~/.bashrc fi # User specific environment and startup programs 3 PATH=$PATH:$HOME/bin 4 ENV=$HOME/.bashrc # or BASH_ENV=$HOME/.bashrc 5 USERNAME="root" 6 export USERNAME ENV PATH 7 mesg n 8 if [ $TERM = linux ] then startx # Start the X Window system fi |
Explanation
Execute (source) the .bashrc file for the login shell.
The PATH variable is appended with a path to the user's bin directory, normally the place where shell scripts are stored.
The BASH_ENV [a] (ENV) file is set to the pathname for the .bashrc file, an initialization file that will be sourced for interactive bash shells and and scripts only if the BASH_ENV (ENV) variable is set. The .bashrc file contains user-defined aliases and functions.
[a] BASH_ENV is used by versions of Bash starting at 2.0,
The variable USERNAME is set to root.
The variables are exported so that they are available to subshells and other processes will know about them.
The mesg command is executed with the n option, disallowing others to write to the terminal.
If the value of the TERM variable is "linux," then startx will start the X window system (the graphical user interface allowing multiple virtual consoles), rather than starting an interactive session in the Linux console window. Because the ~/.bash_profile is only sourced when you log in, the login shell would be the best place to start up your X windows session.
Before bash version 2.0, the BASH_ENV file was simply called the ENV file (same as in Korn shell). The BASH_ENV (ENV) variable is set in the ~/.bash_profile. It is assigned the name of a file that will be executed every time an interactive bash shell or bash script is started. The BASH_ENV (ENV) file will contain special bash variables and aliases. The name is conventionally .bashrc, but you can call it anything you want. The BASH_ENV (ENV) file is not processed when the privileged option is on (bash -p or set -o privileged) or the --norc command line option is used (bash -norc or bash --norc (bash 2.x +)).
The BASH_ENV (ENV) variable is assigned (by convention) the name .bashrc. This file is automatically sourced every time a new or interactive bash shell or bash script starts. It contains settings that pertain only to the Bash shell.
(Sample .bashrc) #If the .bashrc file exists, it is in the user's home directory. #It contains aliases (nicknames for commands) and user-defined #functions. # .bashrc # User specific aliases and functions 1 set -o vi 2 set -o noclobber 3 set -o ignoreeof 4 alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' 5 stty erase ^h # Source global definitions 6 if [ -f /etc/bashrc ]; then . /etc/bashrc fi 7 case "$-" in 8 *i*) echo This is an interactive bash shell ;; 9 *) echo This shell is noninteractive ;; esac 10 history_control=ignoredups 11 function cd { builtin cd $1; echo $PWD; } |
Explanation
The set command with the -o switch turns on or off special built-in options. (See "The set -o Options" on page 270.) If the switch is -o, a minus sign, the option is turned on, and if a plus sign, the option is turned off. The vi option allows interactive command line editing. For example, set -o vi turns on interactive command-line editing, whereas set vi +o turns it off. (See Table 8.2 on page 270.)
The noclobber option is turned on, which prevents the user from overwriting files when using redirection; e.g., sort filex > filex. (See "Standard I/O and Redirection" on page 363.)
When exiting a shell, normally you can type ^d (Control-D). With ignoreeof set, you must type exit.
The alias for rm, rm -i, causes rm to be interactive (-i ), i.e., it will ask the user if it's OK to remove files before actually removing them.The alias for the cp, cp -i, command causes the copy to be interactive.
The stty command is used to set the terminal backspace key to erase. ^h represents the Backspace key.
If a file called /etc/bashrc exists, source it.
If the shell is interactive, the special variable, $-, will contain an "i." If not, you are probably running a script. The case command evaluates $-.
If the value returned from $- matches *i*, i.e., any string containing an "i," then the shell prints "This is an interactive shell."
Otherwise, the shell prints "This shell is noninteractive." If you start up a script, or a new shell at the prompt, you will be able to tell whether or not your shell is interactive. It is only here to let you test your understanding of the terms "interactive" and "noninteractive" shell.
The history_control setting is used to control how commands are saved in the history file. This line says "Don't save commands in the history file, if they're already there."; i.e., ignore duplicates.
This is a user-defined function. When the user changes directories, the present working directory, PWD, is printed. The function is named cd and contains within its definition, the command cd. The special built-in command, called builtin, precedes the cd command within the function definition to prevent the function from going into an infinite recursion; i.e., from calling itself indefinitely.
System-wide functions and aliases can be set in the /etc/bashrc file. The primary prompt is often set here.
(Sample /etc/bashrc) # System wide functions and aliases # Environment stuff goes in /etc/profile # For some unknown reason bash refuses to inherit # PS1 in some circumstances that I can't figure out. # Putting PS1 here ensures that it gets loaded every time. 1 PS1="[u@h W]\$ " 2 alias which="type -path" |
Explanation
System-wide functions and aliases are set here. The primary bash prompt is set to the name of the user (u), and @ symbol, the host machine (h), the basename of the current working directory, and a dollar sign. (See Table 8.3 on page 276.) This prompt will appear for all interactive shells.
Aliases, nicknames for commands, are usually set in the user's .bashrc file. The alias was preset and is available when bash starts up. You use it when you want to find out where a program resides on disk; i.e., what directory it is found in; e.g., which ls will print /bin/ls.
The .profile file is a user-defined initialization file, found in the user's home directory, and sourced once at login if running sh (Bourne shell) or if running bash, and bash cannot find any other of the initialization files listed above. It allows a user to customize and modify his shell environment. Environment and terminal settings are normally put here, and if a window application or database application is to be initiated, it is started here.
(Sample .profile) # A login initialization file sourced when running as sh or the # .bash_profile or .bash_login are not found. 1 TERM=xterm 2 HOSTNAME=`uname -n` 3 EDITOR=/bin/vi 4 PATH=/bin:/usr/ucb:/usr/bin:/usr/local:/etc:/bin:/usr/bin:. 5 PS1="$HOSTNAME $ > " 6 export TERM HOSTNAME EDITOR PATH PS1 7 stty erase ^h 8 go () { cd $1; PS1=`pwd`; PS1=`basename $PS1`; } 9 trap '$HOME/.logout' EXIT 10 clear |
Explanation
The TERM variable is assigned the value of the terminal type, xterm.
Because the uname -n command is enclosed in back quotes, the shell will perform command substitution, i.e., the output of the command (the name of the host machine) will be assigned to the variable HOSTNAME.
The EDITOR variable is assigned /bin/vi. Programs such as mail and history will now have this variable available when defining an editor.
The PATH variable is assigned the directory entries that the shell searches in order to find a Linux program. If, for example, you type ls, the shell will search the PATH until it finds that program in one of the listed directories. If it never finds the program, the shell will tell you so.
The primary prompt is assigned the value of HOSTNAME, the machine name, and the $ and > symbols.
All of the variables listed are exported. They will be known by child processes started from this shell.
A function called go is defined. The purpose of this function is to take one argument, a directory name, cd to that directory, and set the primary prompt to the present working directory. The basename command removes all but the last entry of the path. The prompt will show you the current directory.
The trap command is a signal handling command. When you exit the shell, that is, log out, the .logout file will be executed. The .logout file is a user-defined file containing commands that will be executed just before logging out, commands that will clean up temp files or log the time of log out, etc.
The clear command clears the screen.
When the user logs out (exits the login shell), if a file called ~/.bash_logout exists, it is sourced. This file normally contains commands to clean up temporary files, truncate the history file, record the time of logout, etc.
If bash is invoked with the --noprofile option (e.g., bash --noprofile), then the /etc/profile, ~/.bash_profile, ~/.bash_login, or ~/.profile startup files will not be sourced.
If invoked with the -p option (e.g., bash -p), bash will not read the user's ~/.profile file.
If bash is invoked as sh (Bourne shell), it tries to mimic the behavior of the Bourne shell as closely as possible. For a login shell, it attempts to source only /etc/profile and ~/.profile, in that order. The -noprofile option may still be used to disable this behavior. If the shell is invoked as sh, it does not attempt to source any other startup files.
Another default initalization file, .inputrc, is also read when bash starts up. This file, if it exists in the user's home directory, contains variables to customize key stroke behavior and settings that bind strings, macros, and control functions to keys. The names for the key bindings and what they do are found in the Readline Library, a library that is used by applications that manipulate text. The bindings are used particularly by the built-in emacs and vi editors, when performing command line editing. (See "Command Line Editing" on page 301 for more on readline.)
The set command can take options when the -o switch is used. Options allow you to customize the shell environment. They are either on or off, and are normally set in the BASH_ENV (ENV) file. Many of the options for the set command are set with an abbreviated form. For example, set -o noclobber can also be written, set -C. (See Table 8.2.)
Format
set -o option Turns on the option. set +o option Turns off the option. set -[a-z] Abbreviation for an option; the minus turns it on. set +[a-z] Abbreviation for an option; the plus turns it off.
1 set -o allexport 2 2set +o allexport 3 3set -a 4 4set +a |
Explanation
Sets the allexport option. This option causes all variables to be automatically exported to subshells.
Unsets the allexport option. All variables will now be local in the current shell.
Sets the allexport option. Same as 1. Not every option has an abbreviation. (See Table 8.2.)
Unsets the allexport option. Same as 2.
1 $ set -o braceexpand on errexit off hashall on histexpand on keyword off monitor on noclobber off noexec off noglob off notify off nounset off onecmd off physical off privileged off verbose off xtrace off history on ignoreeof off interactive-comments on posix off emacs off vi on 2 $ set -o noclobber 3 $ date > outfile 4 $ ls > outfile bash: outfile: Cannot clobber existing file. 5 $ set +o noclobber 6 $ ls > outfile 7 $ set -C |
Explanation
With the -o option, the set command lists all the options currently set or not set.
To set an option, the -o option is used. The noclobber option is set. It protects you from overwriting files when using redirection. Without noclobber, the file to the right of the > symbol is truncated if it exists, and created if it doesn't exist.
The output of the Linux date command is redirected to a file called outfile.
This time, the outfile exists. By attempting to redirect the output of ls to outfile, the shell complains that the file already exists. Without noclobber set, it would be clobbered.
With the +o option to the set command, noclobber is turned off.
This time, trying to overwrite outfile is fine because noclobber is no longer set.
Using the -C switch to the set command is an alternate way of turning on noclobber. +C would turn it off.
The shopt (shell options) built-in command is used in newer versions of bash as an alternative to the set command. In many ways shopt duplicates the set built-in command, but it adds more options for configuring the shell. See Table 8.31 on page 379 for a list of all the shopt options. In the following example, shopt with the -p option prints all the available options settings. The -u switch indicates an unset option and -s indicates one that is currently set.
1 $ shopt -p shopt -u cdable_vars shopt -u cdspell shopt -u checkhash shopt -u checkwinsize shopt -s cmdhist shopt -u dotglob shopt -u execfail shopt -s expand_aliases shopt -u extglob shopt -u histreedit shopt -u histappend shopt -u histverify shopt -s hostcomplete shopt -u huponexit shopt -s interactive_comments shopt -u lithist shopt -u mailwarn shopt -u nocaseglob shopt -u nullglob shopt -s promptvars shopt -u restricted_shell shopt -u shift_verbose shopt -s sourcepath 2 $ shopt -s cdspell 3 $ shopt -p cdspell shopt -s cdspell 4 $ cd /hame /home 5 $ pwd /home 6 $ cd /ur/lcal/ban /usr/local/man 7 $ shopt -u cdspell 8 $ shopt -p cdspell shopt -u cdspell |
Explanation
With the -p (for print) option, the shopt command lists all settable shell options and their current values, either set (-s) or unset (-u).
With the -s option, shopt sets (or turns on) an option. The cdspell option causes the shell to correct minor spelling errors on directory names given as arguments to the cd command. It will correct simple typos, insert missing letters, and even transpose letters if it can.
With the -p option and the name of the option, shopt indicates whether or not the option is set. The option has been set (-s).
The output of the pwd command displays the current working directory, showing that the directory was really changed even though the user spelled it wrong.
This time the directory name is missing letters and has a misspelling for the last entry, ban. The shell makes a pretty good attempt to spell out the correct pathname by inserting the missing letters, and correcting ban to man. Because the "b" in ban is the first misspelled character, the shell searches in the directory for an entry that might end with "a" and "n." It finds man.
When used interactively, the shell prompts you for input. When you see the prompt, you know that you can start typing commands. The bash shell provides four prompts: the primary prompt is a dollar sign ($), and the secondary prompt, a right angle bracket symbol (>). The third and fourth prompts, PS3 and PS4 respectively, will be discussed later. The prompts are displayed when the shell is running interactively. You can change these prompts.
The variable, PS1, is set to a string containing the primary prompt. Its value, the dollar sign, appears when you log on and waits for user input, normally a Linux command. The variable PS2 is the secondary prompt, initially set to the right angle bracket character. It appears if you have partially typed a command and then pressed the carriage return. You can change the primary and secondary prompts.
The dollar sign (or bash $) is the default primary prompt. You can change your prompt. Normally prompts are defined in /etc/bashrc or the user initialization file, .bash_profile, or .profile (Bourne shell).
1 $ PS1="$(uname -n) > " 2 chargers > |
Explanation
The default primary prompt is a dollar sign (bash $). The PS1 prompt is being reset to the name of the machine[a] (uname -n) and a > symbol.
[a] The command, uname -n, is executed because it is enclosed in a set of parentheses preceded by a dollar sign. An alternative would be to enclose the command in back quotes. See "Command Substitution" on page 353.)
The new prompt is displayed.
By inserting special backslash-escape sequences into the prompt string, you can customize the prompts. Table 8.3 lists the special sequences.
1 $ PS1="[u@h W]\$ " [ellie@homebound ellie]$ 2 $ PS1="W:d> " ellie:Tue May 18> |
Explanation
You customize the primary bash prompt using special backslash-escape sequences. u evaluates to the user's login name, h to the host machine, and W is the basename for the current working directory. There are two backslashes. The first backslash escapes the second backslash, resulting in $. The dollar sign is protected from shell interpretation and thus printed literally.
The primary prompt is assigned W, the escape sequence evaluating to the basename of the current working directory, and d, the escape sequence evaluating to today's date.
The PS2 variable is assigned a string called the secondary prompt. Its value is displayed to standard error, which is the screen by default. This prompt appears when you have not completed a command or more input is expected. The default secondary prompt is >.
1 $ echo "Hello 2 > there" 3 Hellothere 4 $ 5 $ PS2="––––> " 6 $ echo 'Hi 7 ––––––> ––––––> ––––––>there' Hi there $ 8 $ PS2="s:PS2 > " $ echo 'Hello bash:PS2 > what are bash:PS2 > you bash:PS2 > trying to do? bash:PS2 > ' Hello what are you trying to do? $ |
Explanation
The double quotes must be matched after the string " Hello.
When a newline is entered, the secondary prompt appears. Until the closing double quotes are entered, the secondary prompt will be displayed.
The primary prompt is displayed.
The secondary prompt is reset.
The single quote must be matched after the string 'Hi.
When a newline is entered, the new secondary prompt appears. Until the closing single quote is entered, the secondary prompt will be displayed.
Bash uses the PATH variable to locate commands typed at the command line. The path is a colon-separated list of directories used by the shell when searching for commands. The default path is system-dependent, and is set by the administrator who installs bash. The path is searched from left to right. The dot at the end of the path represents the current working directory. If the command is not found in any of the directories listed in the path, the shell sends to standard error the message " filename: not found. " The path is normally set in the .bash_profile if running the bash shell or .profile file if using sh, the Bourne shell.
If the dot is not included in the path and you are executing a command or script from the current working directory, the name of the script must be preceded with a ./, such as ./program_name, so that shell can find the program.
(Printing the PATH) 1 $ echo $PATH /usr/gnu/bin:/usr/local/bin:/usr/ucb:/bin:/usr/bin:. (Setting the PATH) 2 $ PATH=$HOME:/usr/ucb:/usr:/usr/bin:/usr/local/bin: 3 $ export PATH 4 $ runit bash: runit: command not found 5 $ ./runit < program starts running here > |
Explanation
To set the path, a list of colon-separated directories are assigned to the PATH variable. Note that in this path, the dot is not at the end of the path, perhaps as a security measure.
By exporting the path, child processes will have access to it. It is not necessary to export the PATH on a separate line: It could be written: export PATH=$HOME:/usr/ucb:/bin:., etc., on the same line.
Because the dot is not in the search path, when the program, runit, is executed in the present working directory, bash can't find it.
Because the program name is preceded with a dot and a slash (./), the shell will be able to find it, and execute it, if it is the current working directory.
The hash command controls the internal hash table used by the shell to improve efficiency in searching for commands. Instead of searching the path each time a command is entered, the first time you type a command, the shell uses the search path to find the command, and then stores it in a table in the shell's memory. The next time you use the same command, the shell uses the hash table to find it. This makes it much faster to access a command than having to search the complete path. If you know that you will be using a command often, you can add the command to the hash table. You can also remove commands from the table. The output of the hash command displays the number of times the shell has used the table to find a command (hits) and the full pathname of the command. The hash command with the -r option clears the hash table. An argument of -- disables option checking for the rest of the arguments. Hashing is automatically implemented by bash. Although you can turn it off, if there isn't any compelling reason to do so, don't.
(Printing the PATH) (Command line) 1 hash hits command 1 /usr/bin/mesg 4 /usr/bin/man 2 /bin/ls 2 hash -r 3 hash No commands in hash table 4 hash find hits command 0 /usr/bin/find |
Explanation
The hash command displays the full pathname of commands that have been executed in this login session.(Built-in commands are not listed) The number of hits is the number of times the hash table has been used to find the command.
The -r option to the hash command erases all remembered locations in the hash table.
After the -r option was used in the last command, the hash command reports that there are no commands currently in the table.
If you know you are going to use a command often, you can add it to the hash table by giving it as an argument to the hash command. The find command has been added. The table has zero hits, because the command hasn't been used yet.
The source command (from the C shell) is a built-in bash shell command. The dot command, simply a period, (from the Bourne shell) is another name for source. Both commands take a script name as an argument. The script will be executed in the environment of the current shell; that is, a child process will not be started. All variables set in the script will become part of the current shell's environment. Likewise, all variables set in the current shell will become part of the script's environment. The source (or dot) command is normally used to reexecute any of the initialization files, e.g., .bash_profile, .profile, etc, if they have been modified. For example, if one of the settings, such as the Editor or Term variable, has been changed in the .bash_profile since you logged on, you can use the source command to reexecute commands in the .bash_profile without logging out and then logging back on. A file, such as .bash_profile, or for that matter any shell script, does not need execute permissions to be sourced with either the dot or the source commands.
$ source .bash_profile $ . .bash_profile |
Explanation
The source or dot command executes the initialization file, .bash_profile, within the context of the current shell. Local and global variables are redefined within this shell. The dot command makes it unnecessary to log out and then log back in again after the file has been modified.[a]
[a] If the .bash_profile were executed directly as a script, a child shell would be started. Then the variables would be set in the child shell, and when the child shell exited, the parent shell would not have any of the settings available to it.
After you log on, the bash shell displays its primary prompt, a dollar sign, by default. The shell is your command interpreter. When the shell is running interactively, it reads commands from the terminal and breaks the command line into words. A command line consists of one or more words (or tokens), separated by white space (blanks and/or tabs), and terminated with a newline, generated by pressing the Enter key. The first word is the command, and subsequent words are the command's arguments. The command may be a Linux/UNIX executable program such as ls or date, a user-defined function, a built-in command such as cd or pwd, or a shell script. The command may contain special characters, called metacharacters, which the shell must interpret while parsing the command line. If a command line is too long, the backslash character, followed by a newline, will allow you to continue typing on the next line. The secondary prompt will appear until the command line is terminated.
The first word on the command line is the command to be executed. The command may be a keyword, an alias, a function, a special built-in command or utility, an executable program, or a shell script. The command is executed according to its type in the following order:
Aliases
Keywords (such as if, function, while, until)
Functions
Built-in commands
Executables and scripts
Special built-in commands and functions are defined within the shell, and therefore, are executed from within the context of the current shell, making them much faster in execution. Scripts and executable programs such as ls and date are stored on disk, and the shell, in order to execute them, must first locate them within the directory hierarchy by searching the PATH environment variable; the shell then forks a new shell which executes the script. To find out the type of command you are using—i.e., a built-in command, an alias, a function, or an executable, etc.—use the built-in type command. (See Example 8.17.)
$ type pwd pwd is a shell builtin $ type test test is a shell builtin $ type clear clear is /usr/bin/clear $ type m m is aliased to 'more' $ type bc bc is /usr/bin/bc $ type if if is a shell keyword $ type -path cal /usr/bin/cal $ type which which is aliased to 'type -path' $ type greetings greetings is a function greetings () { echo "Welcome to my world!"; } |
Built-in commands are commands that are part of the internal source code for the shell. They are built-in and readily available to the shell, whereas commands such as date, cal, and finger, are compiled binary programs that reside on the disk. There is less overhead in executing a built-in because it involves no disk operations. Built-in commands are executed by the shell before the programs on disk. Bash has added a new online help system so that you can see all the built-ins, or a description for a particular built-in; help, itself, is a built-in command. See Table 8.32 on page 381 for a complete list of built-in commands.
1 $ help help help: help [pattern ...] Display helpful information about built-in commands. if PATTERN is specified, gives detailed help on all commands matching PATTERN, otherwise a list of the built-ins is printed. 2 $ help pw pwd: pwd Print the current working directory. |
Bash provides three built-in commands that can override the order of command line processing: command, builtin, and enable.
The command built-in eliminates aliases and functions from being looked up in the order of processing. Only built-ins and executables, found in the search path, will be processed.
The builtin command looks up only built-ins, ignoring functions and executables found in the path.
The enable built-in command turns built-ins on and off. By default, built-ins are enabled. Disabling a built-in allows an executable command found on the disk to be to be executed without specifying a full pathname, even if it has the same name as a built-in. (In normal processing, bash searches for built-ins before disk executable commands.) Built-ins become disabled by using the -n switch. A classic example causing confusion for new shell programmers, is naming a script, test. Because test is a built-in command, the shell will try to execute it rather than the user's script, (a built-in is normally executed before any executable program). By typing: enable -n test, the test built-in is disabled, and the user's script will take precedence.
Without options, the enable built-in prints a list of all the built-ins. Each of the following built-ins are described in "Shell Built-In Commands" on page 377.
1 $ enable enable . enable : enable [ enable alias enable bg enable bind enable break enable builtin enable cd enable command enable continue enable declare enable dirs ..... enable read enable readonly enable return enable set enable shift enable shopt ..... enable type enable typeset enable ulimit enable umask enable unalias enable unset enable wait 2 enable -n test 3 function cd { builtin cd; echo $PWD; } |
Explanation
The enable built-in, without any options, displays a complete list of all bash shell built-in commands. This example shows just part of that list.
With the -n switch, the test built-in command is disabled. Now, you execute your script named "test" without worrying about the built-in test being executed instead. It's not good practice to name a script by the same name as an operating system command, because if you try to run the same script in another shell, the disabling of built-ins doesn't exist.
The function is called cd. The builtin command causes the cd within the function definition to be called instead of the function cd, which would cause an endless recursive loop.
After a command or program terminates, it returns an exit status to the parent process. The exit status is a number between 0 and 255. By convention, when a program exits, if the status returned is zero, the command was successful in its execution. When the exit status is nonzero, the command failed in some way. If a command is not found by the shell, the exit status returned is 127. If a fatal signal causes the command to terminate, the exit status is 128 plus the value of the signal that caused it to die.
The shell status variable, ?, is set to the value of the exit status of the last command that was executed. Success or failure of a program is determined by the programmer who wrote the program.
1 $ grep ellie /etc/passwd ellie:MrHJEFd2YpkJY:501:501::/home/ellie:/bin/bash 2 $ echo $? 0 3 $ grep nicky /etc/passwd 4 $ echo $? 1 5 $ grep ellie /junk grep: /junk: No such file or directory 6 $ echo $? 2 7 $ grip ellie /etc/passwd bash: grip: command not found 8 $ echo $? 127 9 $ find / -name core ^C User presses Control-C 10 $ echo $? 130 |
Explanation
The grep program searches for the pattern "ellie" in the /etc/passwd file and is successful. The line from /etc/passwd is displayed.
The ? variable is set to the exit value of the grep command. Zero indicates successful status.
The grep program cannot find user nicky in the /etc/passwd file.
The grep program cannot find the pattern; the ? variable return value is nonzero. An exit status of 1 indicates failure.
The grep fails because the /junk file cannot be opened.The grep error message is sent to standard error, the screen.
The command, grip, is not found by the shell.
Because the command is not found, the exit status, 127, is returned.
The find command is interrupted when the SIGINT signal is sent by pressing Control-C. The signal number for Ctrl-C is 2.
The status returned from a process that has been killed is 128 + the number of the signal; i.e., 128 + 2.
A command line can consist of multiple commands. Each command is separated by a semicolon, and the command line is terminated with a newline. The exit status is that of the last command in the chain of commands.
$ ls; pwd; date
|
Explanation
The commands are executed from left to right, one after the other, until the newline is reached.
Commands may also be grouped so that all of the output is either piped to another command or redirected to a file.
$ ( ls; pwd; date ) > outputfile
|
Explanation
The output of each of the commands is sent to the file called outputfile. The spaces inside the parentheses are necessary.
With conditional execution, two command strings are separated by the special metacharacters, double ampersands (&&) and double vertical bars(||). The command on the right of either of these metacharacters will or will not be executed based on the exit condition of the command on the left.
$ cc prgm1.c –o prgm1 && prgm1
|
Explanation
If the first command is successful (has a zero exit status), the second command after the && is executed; i.e., if the cc program can successfully compile prgm1.c, the resulting executable program, prgm1, will be executed.
$ cc prog.c >& err || mail bob < err
|
Explanation
If the first command fails (has a nonzero exit status), the second command after the || is executed; i.e., if the cc program cannot compile prog.c, the errors are sent to a file called err, and user bob will be mailed the err file.
Normally, when you execute a command, it runs in the foreground, and the prompt does not reappear until the command has completed execution. It is not always convenient to wait for the command to complete. When you place an ampersand (&) at the end of the command line, the shell will return the shell prompt immediately and execute the command in the background concurrently. You do not have to wait to start up another command. The output from a background job will be sent to the screen as it processes. Therefore, if you intend to run a command in the background, the output of that command might be redirected to a file or piped to another device, such as a printer, so that the output does not interfere with what you are doing.
The ! variable contains the PID number of the last job put in the background. (See "Job Control" on page 288 for more on background processing.)
1 $ man sh | lp& 2 [1] 1557 3 $ kill -9 $! |
Explanation
The output of the man command (the manual pages for the Linux command) is piped to the printer. The ampersand at the end of the command line puts the job in the background.
There are two numbers that appear on the screen: the number in square brackets indicates that this is the first job to be placed in the background; the second number is the PID, or the process identification number of this job.
The shell prompt appears immediately. While your program is running in the background, the shell is waiting for another command in the foreground. The ! variable evaluates to the PID of the job most recently put in the background. If you get it in time, you will kill this job before it goes to the print queue.
Job control is a powerful feature of the bash shell that allows you to selectivly run programs, called jobs, in the background or foreground. A running program is called a process or a job and each process has a process id number, called the PID. Normally, a command typed at the command line is running in the foreground and will continue until it has finished unless you send a signal by pressing Ctrl-C or Ctrl- to terminate it. With job control you can send a job to the background and let it keep running; you can stop a job by pressing Ctrl-Z, which sends the job to the background and suspends it; you can cause a stopped job to run in the background; you can bring a background job back to the foreground; and you can even kill the jobs you have running in the background or foreground. For a list of job commands, see Table 8.4 on page 290.
By default, job control is already set (some older versions of UNIX do not support this feature). If disabled, it can be reset by any one of the following commands:
Format
set -m (set job control in the .bashrc file) set -o monitor (set job control in the .bashrc file) bash -m -i (set job control when invoking interactive bash)
1 $ vi [1]+ Stopped vi 2 $ sleep 25& [2] 4538 3 $ jobs [2]+ Running sleep 25& [1]– Stopped vi 4 $ jobs –l [2]+ 4538 Running sleep 25& [1]– 4537 Stopped vi 5 $ jobs %% [2]+ 4538 Running sleep 25& 6 $ fg %1 7 $ jobs -x echo %1 4537 8 $ kill %1 or kill 4537 [1]+ Stopped vi Vim: Caught deadly signal TERM Vim: Finished. [1]+ Exit 1 vi |
Explanation
After the vi editor is invoked, you can press ^Z (Control-Z) to suspend the vi session. The editor will be suspended in the background, and after the message Stopped appears, the shell prompt will appear immediately.
The ampersand at the end of the command causes the sleep command, with an argument of 25, to execute in the background. The notation [2] means that this is the second job to be run in the background and the PID of this job is 4538.
The jobs command displays the jobs currently in the background.
The jobs command with the -l option displays the processes (jobs) running in the background and the PID numbers of those jobs.
The %% argument causes jobs to display the most recent command put in the job table.
The fg command followed by a percent sign and the job number will bring that numbered job into the foreground. Without a number, fg brings the most recently backgrounded job back into the foreground.
The -x option can be used to print just the PID number of the job. %1 refers to the vi session that was stopped in the first example.
The kill command sends a TERM signal to the process and kills it. The vi program is killed. You can specify either the job number or the PID number as arguments to the kill command.
Command | Meaning |
---|---|
jobs | Lists all the jobs running. |
^Z (Ctrl-Z) | Stops (suspends) the job; the prompt appears on the screen. |
bg | Starts running the stopped job in the background. |
fg | Brings a background job to the foreground. |
stop | Suspends a background job. |
stty tostop | Suspends a background job if it sends output to the terminal. |
kill | Sends the kill signal to a specified job. |
wait [n] | Waits for a specified job and returns its exit status, where n is a PID or job number. |
Argument to jobs command | Represents |
---|---|
%n | Job number n. |
%sting | Job name starting with string. |
%?string | Job name containing string. |
%% | Current job. |
%+ | Current job. |
%- | Previous job, before current job. |
-r | Lists all running jobs. |
-s | Lists all suspended jobs. |
Two new options were added to the jobs command in bash versions 2.x. They are the -r and -s options. The -r option lists all running jobs, and the -s option lists all stopped jobs.
The disown built-in command (bash 2.x) removes a specified job from the job table. After the job has been removed, the shell will no longer recognize it as a viable job process and it can only be referenced by its process id number.
3.135.196.172