Introduction to Bash

With many developers using the Open Source development tools in HP-UX 11i, there is a lot of interest in Bash. Bash is widely used, although not required, when using GNU tools. In addition, the Linux-based UNIX operating systems I have used configure Bash as the default shell. Bash is covered in this section on a Linux system, however, the features of Bash covered exist on HP-UX as well. Bash possesses many of the fine features of other shells, and in fact derives its name from Bourne Again SHell, which is a dead giveaway that it possesses at least some of the features of the Bourne shell. Bash is similar to other shells in that it provides a user interface to UNIX. You can use the Bash shell in the following three ways:

  • Interactively type commands on the command line.

  • Group commonly executed sets of commands into command files that you can execute by typing the name of the file.

  • Create Bash shell programs using the structured programming techniques of the shell.

These three techniques are listed in the order in which you'll probably use them. First, you log in and use interactive commands. Then you group together commonly used commands and execute them with a single command. Finally, you may want to create sophisticated shell scripts.

For this reason, I'll describe these aspects of the Bash shell in the order in which they are listed. The command file and programming aspects of the Bash shell are covered in Chapter 28. Bash is very similar to the KornShell, which is the shell used in the shell programming chapter. You can, therefore, use the shell programming chapter as an introduction to programming with Bash as well. Keep in mind, however, that differences always occur when programming with one shell rather than another.

Issuing Commands

The first activity you perform after you log into the system is to issue commands at the prompt. A command you may want to issue immediately is ls -al. Here is what I see on my system after executing this command to check my present working directory and producing a long listing of all files when logged in as root:

# pwd
# ls -al
total 46
drwxr-xr-x   5 root     root         1024 Nov 26 19:40 .
drwxr-xr-x  20 root     root         1024 Nov  8 20:10 ..
-rw-r--r--   1 root     root          964 Nov 26 19:40 .bash_history
-rw-r--r--   1 root     root          674 Feb  5  1997 .bashrc
-rw-r--r--   1 root     root          602 Feb  5  1997 .cshrc
-rw-r--r--   1 root     root        14815 Nov  8 20:09 .fvwmrc.menus.prep
-rw-r--r--   1 root     root          116 Feb  5  1997 .login
-rw-r--r--   1 root     root          234 Feb  5  1997 .profile
drwxr-xr-x   2 root     root         1024 Nov  8 14:10 .seyon
-rw-r--r--   1 root     root         4276 Nov  8 20:09 XF86Config
-r--r--r--   1 root     root        13875 Nov  8 20:05 XF86Config.bak
drwxrwxrwx   2 root     root         1024 Nov 26 19:40 book
drwxr-xr-x   5 root     root         1024 Nov 14 18:12 lg
-rw-r--r--   1 root     root            0 Nov 26 19:40 typescript
#

Among the files produced in the long listing of all files is a Bash startup file called .bashrc . The following shows the contents of the .bashrc file:

# cat .bashrc
# ~/.bashrc --
#   The individual per-interactive-shell startup file for bash

. /etc/profile

# try solve this tedious 'Backspace vs. Delete' problem...
if [ -z "$TERM" ]; then
  echo ".bashrc: TERM empty: this shouldn't happen!" 1>&2
  echo "   Please contact '[email protected]'" 1>&2
else
  case $TERM in
  linux*)
    stty erase '^?'
    ;;
  *)
    stty erase '^H'
    ;;
  esac
fi

# general environment settings
#export GROFF_TYPESETTER=latin1
#export LC_CTYPE=iso-8859-1
export LESSCHARSET=latin1
#export METAMAIL_PAGER=less

HISTSIZE=100

alias which='type -path'
alias h=history
alias j="jobs -l"
alias l="ls -Fax"
alias ll="ls -Alg"
alias pd=pushd
alias z=suspend

#

The .bashrc file has some interesting contents. Among them is a value for HISTSIZE, which we'll get into shortly, and a set of aliases. These aliases are "shortcuts" for long commands. When I issue the ll command, for instance, I am really issuing the ls -Alg command.

I may execute both the local .profile shown in the earlier long listing as well as /etc/profile. /etc/profile usually performs setup for all users who log into the system. The following is a listing of /etc/profile:

# cat /etc/profile
# /etc/profile
# System wide environment and startup programs
# Functions and aliases go in $HOME/.bashrc

PATH="/bin:/usr/bin:/opt/bin:/usr/X11R6/bin:/usr/openwin/bin:/usr/TeX/bin:/usr/local/bin"

umask 022

if [ 'id -gn' = 'id -un' ] && [ 'id -u' != 0 ]; then
  umask 002
fi

if [ -z "$UID" ]; then
  UID='id -u'
fi

if [ "$UID" = 0 ]; then
  PATH=/sbin:/usr/sbin:$PATH
else
  PATH=$PATH:
fi
USER='id -un'
LOGNAME=$USER

export PATH USER LOGNAME

HOSTNAME='/bin/hostname'
MAIL="/var/spool/mail/$USER"

export HOSTNAME MAIL

if [ -n "$BASH_VERSION" ]; then
  # (aliases now in $HOME/.bashrc, resp. /etc/skel/.bashrc)
  export PS1="[u@h W]\$ "
  export HISTSIZE=100
fi

#

We'll also cover some of the contents of /etc/profile.

Initializing the History List in .bashrc

The Bash shell can keep a history list of the commands you have issued. If you wish to reissue a command or view a command you earlier issued, you can use the history list.

You can specify any number of commands to be included in the history list. The following line in .bashrc sets the history list to 100:

set history = 100

One hundred commands will be saved in the history list. When you log, out the last 100 commands you have issued are stored in the history list. The next time you log in you can view these 100 commands; however, as you issue commands, the oldest commands fall off the history list. This fact is shown in the following example:

# history
    2  more history
    3   ll
    4  cd ..
    5  pwd
    6  cd ..
    7  ll
    8  cd ..
    9  ll
   10  ll log
   11  cd log
   12  more *
   13  l
   14  ll
   15  cd /
   16  ll
   17  cd
   18  XF86Setup
   19  XF86Setup
   20  startx
   21  ll
   22  pwd
   23  ll
   24  ll /
   25  XF86Setup
   26  ll
   27  startx
   28  find / -name XF86Config*
   29  cp /usr/X11R6/lib/X11/XF86Config.eg .
   30  ll
   31  XF86Setup
   32  XF86Setup
   33  startx
   34  ll
   35  mv XF86Config.eg XF86Config
   36  XF86Setup
   37  startx
   38  shutdown -h now
   39  man ls
   40  man ll
   41  man ls
   42  man file
   43  lsr
   44  man chmod
   45  man chmod
   46  shutdown -h now
   47  pwd
   48  ls -l
   49  pwd
   50  ls -a
   51  ls -al
   52  pwd
   53  ls -al
   54  more .profile
   55  more .bashrc
   56
   57  alias
   58  ll
   59  pwd
   60  script
   61  script
   62  scrit
   63  script
   64  more .bashrc
   65  more .bashrc
   66   ll
   67  more .profile
   68   ll
   69  more .bashrc | grep P
   70  more .profile | grep P
   71  env
   72  more /.profile
   73  more /etc/profile
   74  more /etc/profile | grep PS
   75  find / -name *profile* -print
   76  more .bashrc
   77   more .bashrc
   78  ll /etc/profi*
   79  cp /etc/profile /etc/profile.orig
   80  vi /etc/profile
   81  exit
   82  cp /etc/profile.orig /etc/profile
   83  history
   84
   85  exit
   86  history
   87  history
   88    ll
   89    ll
   90  history
   91  ll /etc/profi*
   92  ll /etc/profi*
   93   more .bashrc
   94    history
   95  ll
   96  cd /root
   97  ll
   98  history | more
   99   history | more
  100   exit
  101  history

Notice in this example that command number 100 is the exit, or command to log out, from the last session. Command number 101 is the history command I issued immediately upon establishing the next session.

Recalling from the History List

All these commands (cp, more, find, ll) are in the history list with their corresponding numbers. You can repeat the last command with !!, the 89th command with !89, and the last command that started with "m" with !m, all of which are shown in the following example:

# !!
history
    3   ll
    4  cd ..
    5  pwd
    6  cd ..
    7  ll
    8  cd ..
    9  ll
   10  ll log
   11  cd log
   12  more *
   13  l
   14  ll
   15  cd /
   16  ll
   17  cd
   18  XF86Setup
   19  XF86Setup
   20  startx
   21  ll
   22  pwd
   23  ll
   24  ll /
   25  XF86Setup
   26  ll
   27  startx
   28  find / -name XF86Config*
   29  cp /usr/X11R6/lib/X11/XF86Config.eg .
   30  ll
   31  XF86Setup
   32  XF86Setup
   33  startx
   34  ll
   35  mv XF86Config.eg XF86Config
   36  XF86Setup
   37  startx
   38  shutdown -h now
   39  man ls
   40  man ll
   41  man ls
   42  man file
   43  lsr
   44  man chmod
   45  man chmod
   46  shutdown -h now
   47  pwd
   48  ls -l
   49  pwd
   50  ls -a
   51  ls -al
   52  pwd
   53  ls -al
   54  more .profile
   55  more .bashrc
   56
   57  alias
   58  ll
   59  pwd
   60  script
   61  script
   62  scrit
   63  script
   64  more .bashrc
   65  more .bashrc
   66   ll
   67  more .profile
   68   ll
   69  more .bashrc | grep P
   70  more .profile | grep P
   71  env
   72  more /.profile
   73  more /etc/profile
   74  more /etc/profile | grep PS
   75  find / -name *profile* -print
   76  more .bashrc
   77   more .bashrc
   78  ll /etc/profi*
   79  cp /etc/profile /etc/profile.orig
   80  vi /etc/profile
   81  exit
   82  cp /etc/profile.orig /etc/profile
   83  history
   84
   85  exit
   86  history
   87  history
   88    ll
   89    ll
   90  history
   91  ll /etc/profi*
   92  ll /etc/profi*
   93   more .bashrc
   94    history
   95  ll
   96  cd /root
   97  ll
   98  history | more
   99   history | more
  100   exit
  101  history
  102  history
# !89
  ll
total 44
-rw-r--r--   1 root     root          956 Nov 26 19:33 .bash_history
-rw-r--r--   1 root     root          674 Feb  5  1997 .bashrc
-rw-r--r--   1 root     root          602 Feb  5  1997 .cshrc
-rw-r--r--   1 root     root        14815 Nov  8 20:09 .fvwmrc.menus.prep
-rw-r--r--   1 root     root          116 Feb  5  1997 .login
-rw-r--r--   1 root     root          234 Feb  5  1997 .profile
drwxr-xr-x   2 root     root         1024 Nov  8 14:10 .seyon
-rw-r--r--   1 root     root         4276 Nov  8 20:09 XF86Config
-r--r--r--   1 root     root        13875 Nov  8 20:05 XF86Config.bak
drwxrwxrwx   2 root     root         1024 Nov 13 21:25 book
drwxr-xr-x   5 root     root         1024 Nov 14 18:12 lg
-rw-r--r--   1 root     root            0 Nov 26 19:36 typescript
# !m
more .bashrc
# ~/.bashrc --
#   The individual per-interactive-shell startup file for bash

. /etc/profile

# try solve this tedious 'Backspace vs. Delete' problem...
if [ -z "$TERM" ]; then
  echo ".bashrc: TERM empty: this shouldn't happen!" 1>&2
  echo "   Please contact '[email protected]'" 1>&2
else
  case $TERM in
  linux*)
    stty erase '^?'
    ;;
  *)
    stty erase '^H'
    ;;
  esac
fi

# general environment settings
#export GROFF_TYPESETTER=latin1
#export LC_CTYPE=iso-8859-1
[7m--More--(70%)[m
export LESSCHARSET=latin1
#export METAMAIL_PAGER=less

HISTSIZE=100

alias which='type -path'
alias h=history
alias j="jobs -l"
alias l="ls -Fax"
alias ll="ls -Alg"
alias pd=pushd
alias z=suspend

[root@nycald1 /root]#
Script done on Thu Nov 26 19:39:51 1998

Table 27-8 includes some of the more commonly used history list recall commands:

Table 27-8. Recalling from the History List
CommandDescriptionExample
!NIssue command N!2
!!Issue last command!!
!-NIssue Nth command from last command issued!-N
!strIssue last command starting with str!c
!?str?Issue last command that had str anyplace in command line!?cat?
!{str1}str2Append str2 to last command with str1!{cd} /tmp
^str1^str2^Substitute str2 for str1 in last command^cat^more^

Editing on the Command Line

Using the history list is a great way of viewing and reissuing commands. Bash also supports command-line editing. You can use the up arrow key to move back one command in the history list. When you press the up arrow key, the last command from the history list appears on the command line. Every time you press the up arrow key, you move back one more command in the history list. When a command appears on the command line, you can press the "Enter" key to issue the command. You can modify the command by using the left and right arrow keys to move to a point in the command line and type additional information, or use the "backspace" and "delete" keys to remove information from the command line.

Aliases in .bashrc

An alias is a name that you select for a frequently used command or series of commands. You can use the .bashrc file as a place where your aliases are stored and read every time you log in. In the earlier .bashrc file, seven aliases were already set up. You can add additional aliases in the .bashrc file or define aliases at the command-line prompt, but these will be cleared when you log out.

Here is a list of the aliases that are already set up for us in the .bashrc file and an example of running the aliases l and ll:

# alias
alias h='history'
alias j='jobs -l'
alias l='ls -Fax'
alias ll='ls -Alg'
alias pd='pushd'
alias which='type -path'
alias z='suspend'
#
# l
./                ../                 .bash_history        .bashrc
.cshrc            .fvwmrc.menus.prep  .login               .profile
.seyon/           XF86Config          XF86Config.bak       book/
lg/               typescript
#
# ll
total 44
-rw-r--r--   1 root     root          970 Nov 26 21:35 .bash_history
-rw-r--r--   1 root     root          674 Feb  5  1997 .bashrc
-rw-r--r--   1 root     root          602 Feb  5  1997 .cshrc
-rw-r--r--   1 root     root        14815 Nov  8 20:09 .fvwmrc.menus.prep
-rw-r--r--   1 root     root          116 Feb  5  1997 .login
-rw-r--r--   1 root     root          234 Feb  5  1997 .profile
drwxr-xr-x   2 root     root         1024 Nov  8 14:10 .seyon
-rw-r--r--   1 root     root         4276 Nov  8 20:09 XF86Config
-r--r--r--   1 root     root        13875 Nov  8 20:05 XF86Config.bak
drwxrwxrwx   2 root     root         1024 Nov 26 19:41 book
drwxr-xr-x   5 root     root         1024 Nov 14 18:12 lg
-rw-r--r--   1 root     root            0 Nov 26 21:35 typescript
#

These are all very useful indeed, but let's now set up our own alias. Suppose that we want to know how many processes are running on the system. We'll create an alias called "procs" that does this for us. The ps command produces a list of processes. We'll issue ps and pipe (|) this output to wc with the "l" option to tell us how many lines are present. The pipe (|) directs the output of ps to be used as the input to wc. The ps command produces a list of processes, and wc -l gives us a count of the number of lines. Therefore, we'll know the total number of processes running. The following example first shows the output of ps, then our alias command, and finally the output produced by the alias command:


# ps
  PID TTY STAT  TIME COMMAND
  188   2 S    0:00 /sbin/getty tty2 VC linux
  189   3 S    0:00 /sbin/getty tty3 VC linux
  190   4 S    0:00 /sbin/getty tty4 VC linux
  191   5 S    0:00 /sbin/getty tty5 VC linux
  192   6 S    0:00 /sbin/getty tty6 VC linux
  619   1 S    0:00 login root
  620   1 S    0:00 -bash
  642   1 S    0:00 script
  643   1 S    0:00 script
  644  p0 S    0:00 bash -i
  656  p0 R    0:00 ps
#
# alias procs='echo "Number of processes are: ";ps | wc -l'
#
# procs
Number of processes are: 11
#

This alias works wonderfully. All we have to type is "procs" to see the number of processes running on our system.

A lot of quoting takes place in this command line. To understand what is taking place on this line, consult Table 27-9:

Table 27-9. Shell Quoting
Character(s)Description
'cmd'Single quote means to take the string character literally
"str"Double quote means allow command and variable substitution
cEscape character prevents everything following it from printing, including new line
'str'Grave means to execute command and substitute output

Applying Table 27-9 to the earlier procs alias, we can see what comprises this alias. The alias begins with a single quote, which means to execute the command(s) within the single quotes. The first command is echo, which uses double quotes to specify the characters to echo. We could have added the escape character c, which would have prevented a new line from being printed. The semicolons separate commands. ps is then run to produce a list of processes, and the output is piped (|) to word count (wc), which produces a count of the number of lines, as shown in Figure 27-9:

Figure 27-9. Quoting Example


As you can see in Figure 27-9, some of the quoting becomes tricky. An understanding of quoting is important if you wish to modify and reuse existing shell scripts or craft your own.

Command and Path Completion

Bash sometimes knows what you're thinking. You can type part of a command or pathname, and Bash can complete the remainder for you. You can type part of a command or pathname and use the "tab" key to complete the command. If, for instance, you wish to issue the runlevel command to view the current system run level, but can't remember the full command, you can type "run" and press the tab key and the command is completed for you, as shown in the following example:

# run<tab key>level
 N 3

Bash determined that the only command that starts with "run" is runlevel and completed the command.

As long as you issue the command or pathname to the extent that it is unique, then Bash completes it for you. If the command or pathname is not unique, then Bash shows you the options for completing the command. The following example shows typing "ru" and two tabs to get a list of commands that start with "ru":

# ru<tab key><tab key>
runlevel  rusers

You can see from this example that typing "ru" produced two possible commands - runlevel and rusers.

This great completion also works for path names. If you change directory to "/b," you get the following result:

# cd /b<tab key><tab key>
bin  boot

Because two directories at the root level begin with "b," Bash could not determine which of the two you wanted and listed both.

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

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