This article is excerpted from the recently published book "Learning the bash Shell."
The.bash_profile,.bash_logout, and.bashrc files
Three files in your home directory have a special meaning to bash, providing a way for you to set up your account environment automatically when you log in and when you invoke another bash shell, and allowing you to perform commands when you log out. 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.
The most important bash file,.bash_profile, is read and the commands in it executed by bash every time you log in to the system. 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. For example:
source executes the commands in the specified file, in this case.bash_profile, including any commands that you have added.
bash allows two synonyms for.bash_profile:.bash_login, derived from the C shell's file named.login, and.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.
If you have used Unix for any length of time you will have noticed that there are many commands available and that some of them have cryptic names. Sometimes the commands you use the most have a string of options and arguments that need to be specified. Wouldn't it be nice if there were a feature that let you rename the commands or allowed you to type in something simple instead of half a dozen options? Fortunately, bash provides such a feature: the alias.
Aliases can be defined on the command line, in your.bash_profile, or in your.bashrc, using this form:
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 and are therefore excellent candidates for aliasing, the classic example being:
grep, the Unix file-searching utility, was named as an acronym for something like "Generalized Regular Expression Parser." This acronym may mean something to a computer scientist, but not to the office administrator who has to find Fred in a list of phone numbers. If you have to find Fred 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
This can be handy, but we feel you're probably better off suffering with the error message and getting the correct spelling under your fingers. Another common way to use an alias is as a shorthand for a longer command string. For example, you may have a directory to which you need to go often. It's buried deep in your directory hierarchy, so you want to set up an alias that will allow you to
cd there without typing (or even remembering) the entire pathname:
alias cdvoy='cd sipp/demo/animation/voyager'
Notice the quotes around the full
cd command; these are necessary if the string being aliased consists of more than one word.
As another example, a useful option to the
ls command is
-F: it puts a slash (/) after directory files and an asterisk (*) after executable files. Since typing a dash followed by a capital letter is inconvenient, many people define an alias like this:
alias lf='ls -F'
A few things about aliases are important to remember. First, bash makes a textual substitution of the alias for that which it is aliasing; it may help to imagine bash passing your command through a text editor or word processor and issuing a "change" or "substitute" command before interpreting and executing it. Any special characters (such as wildcards like * and ?) that result when the alias is expanded are interpreted properly by the shell. For example, to make it easier to print all of the files in your directory, you could define the alias:
alias printall='pr * | lpr'
Second, keep in mind that aliases are recursive, which means that it is possible to alias an alias. A legitimate objection to the previous example is that the alias, while mnemonic, is too long and doesn't save enough typing. If we want to keep this alias but add a shorter abbreviation, we could define:
With recursive aliasing available it would seem possible to create an infinite loop:
alias ls='ls -l'
bash ensures that this loop cannot happen, 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. The above command will work as expected (typing
ls produces a long list with permissions, sizes, owners, etc.), while in more meaningless situations such as:
alias listfile=ls alias ls=listfile
the alias listfile is ignored.
Aliases can be used only for the beginning of a command string -- albeit with certain exceptions. In the
cd example above, you might want to define an alias for the directory name alone, not for the entire command. But if you define:
and then type
cd anim, bash will probably print a message like anim: No such file or directory.
An obscure feature of bash's alias facility -- one 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, then bash tries to do alias substitution on the next word on the command line. To make the value of an alias end in a blank, you need to surround it with quotes.
Here is how you would use this capability to allow aliases for directory names, at least for use with the
cd command. Just define:
alias cd='cd '
This causes bash to search for an alias for the directory name argument to
cd, which in the previous example would enable it to expand the alias anim correctly.
Finally, there are a few useful adjuncts to the basic
alias command. 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. If you type
alias without any arguments, you get a list of all the aliases you have defined. The command
unalias name removes any alias definition for its argument.
Aliases are very handy for creating a comfortable environment, but they have essentially been superseded by shell scripts and functions, which give you everything aliases do plus much more. 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.