20061019

From Wsms

Jump to: navigation, search

previous next

GO TO:
Linux Class Notes
Basic log files and security tools


Thursday Oct 19 2006

Contents

Customizing the bash shell with the alias command and shell scripts

Yesterday we learned how to set variables in bash and customize your shell by modifying ~/.bashrc and ~/.bash_profile. We also showed how the system administrator, aka the root user, can change the defaults for all the users on his system by changing /etc/bashrc and /etc/profile. One of the beauties of the concept of a shell is that you can tell it to do things your way. When you enter a command at the bash prompt, you may be running a compiled program (e.g. /bin/ls) or you may be running a command that is built into bash (e.g. set). You can easily modify the way bash commands run using the alias command. And, you can build your own customized commands using the bash scripting language.

For something to qualify as a programming language, it must allow you to test for certain circumatances and take actions based on the results of those tests. For example, if a file exists, you want to read it. If the file doesn't exist or can't be read, you want your program to load certain default values. Bash scripts are an example of a programming language. HTML is not a programming language.

It is possible to build very elaborate programs with Bash. The book Learning the Bash Shell has an example of an interactive bash shell scripting debugger written in bash. Dave Taylor has been writing a Linux Journal column about bash and bash programming for the last year or so. The content is available online: http://www.linuxjournal.com/article/8563 http://www.linuxjournal.com/article/8626 http://www.linuxjournal.com/article/8692 http://www.linuxjournal.com/article/8704 http://www.linuxjournal.com/article/8774 http://www.linuxjournal.com/article/8860 http://www.linuxjournal.com/article/8936 http://www.linuxjournal.com/article/8988 http://www.linuxjournal.com/article/9051 http://www.linuxjournal.com/article/9102 http://www.linuxjournal.com/article/9168 http://www.linuxjournal.com/article/9257 Some of the articles show how to build a blackjack program in bash.

My Favorite bash Tips and Tricks by Prentice Bisbal is another worthwhile article from Linux Journal.

In bash variables are accessed by prepending their name with the $ character. For example, $PATH defines where bash will look for executable commands to run for you. As a user, you can look at your path with:

[ggeller@rop ~]$ echo $PATH
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/ggeller/bin

PATH is just a shell variable, albeit an important one. You can create other shell variables if you want to.

Note that most of us will never write scripts or functions, but it is good to know a few things about them so that you can understand what your Linux system is doing and perhaps fix it when things go wrong. Up until recently, the WSMS class devoted a lot of class time to bash scripting. The sylabus is now changed to cover perl scripting in depth and deemphasize bash scripting. Perl has many advantages over bash that will be apparent later in the session. For now just remember that perl works on both Windows and Linux, but bash does not work on Windows.

The alias command

The alias command gives you some capability to modify or override the behavior of pre-existing commands. In our system, the command ls has been aliased so that it displays different types of files in different colors. The shell can show you the alias that is assigned to ls:

[ggeller@rop ~]$ which ls
alias ls='ls --color=tty'
        /bin/ls

This output tells us that ls is aliased to ls --coloy=tty. And that ls itself is actually /bin/ls. You can look at man ls to see what that particular option means. The bare alias command give you a list of all the aliases that are in effect:

[ggeller@rop ~]$ alias
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

As a user of a system you may define your own alises with the alias command followed by some arguments.

[ggeller@rop ~]$ alias my_dir='ls -lR'
[ggeller@rop ~]$ which my_dir
alias my_dir='ls -lR'
        /bin/ls
[ggeller@rop ~]$ my_dir
.:
total 4620
-rw-r--r-- 1 ggeller students      85 Oct 18 08:10 test
-rw-r--r-- 1 ggeller students      83 Oct 17 11:04 test.dos
-rw-r--r-- 1 ggeller students      80 Oct 17 11:05 test.unix
-rw-r--r-- 1 ggeller students 4679831 Oct 17 18:52 wsms.wikiplanet.com-20061017.tar.bz2
-rw-r--r-- 1 ggeller students      54 Oct 17 11:56 yum.list

Note that when you ask bash to execute the command my_dir, it uses the alias you have defined to call the ls program with the options you specified. When the user defines an alias like this, it is defined for that sesion and for that ocurrence of the shell. It goes away when the session is over. To make the defintion persistent, edit one of those startup files we are familiar with, like .bash_profile. It is not possible for regular users to set system-wide aliases that effect other users. However, the root user may do this by editing /etc/bashrc or /etc/profile.

Use the unalias command to remove an alias for the duration of a session.

[ggeller@rop ~]$ unalias my_dir
[ggeller@rop ~]$ which my_dir
/usr/bin/which: no my_dir in (/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/ggeller/bin)
[ggeller@rop ~]$ my_dir
-bash: my_dir: command not found


Bash Functions

The function command in bash defines a section of code that is stored in memory during the session. Since functions are stored in RAM, they can execute very rapidly. A simple function be defined anu used in the shell like this:

[ggeller@rop ~]$ function hi_there()
> {
> echo "hello world"
> }
[ggeller@rop ~]$ hi_there
hello world

Notice that bash prompt changes for the second, third and fourth lines of input. The hi_there function exists only in the context of the current session. To make it persistent across sessions, add the definition to ~/.bashrc or ~/.bash_profile. Look at /etc/init.d/functions for examples of some fairly sophisticated bash functions.

Bash Scripts

A bash script a file stored on the hd. It must read from disk and loaded into RAM before it is executed. Therefor, a script is slower than a function. Note, however, that performance is rarely a consideration in the context.

As administrators, we allways are dealing with scripts. Many scripts that are critical to the operation of the Linux system can be found in /etc/sysconfig and /etc/init.d. You need to have a basic understanding of scripting in order to understand the system. To write a script, you can use an editor, like vi or emacs.

[ggeller@rop ~]$ vi my_script.sh

In vi, edit the file so that it reads:

#!/bin/bash
echo "hello world"

Your vi session should look something like this:
Image:20061019-010-vi.gif
Save the file and quit vi. Check the file from the command line and execute it:

[ggeller@rop ~]$ cat my_script.sh
#!/bin/bash
echo "hello world"
[ggeller@rop ~]$ . my_script.sh
hello world

The first line in a script file, is a special line called the "shebang" line. It specifies the interpreter to be used. Examples are #!/bin/bash, and #!/etc/perl. The shebang must absolutely be the first line, or it will be ignored. It starts with the #! symbols, and it is processed by the bash shell. Other lines in script files that begin with # are ignored. In the second line, it is standard practice to put the name of the author and the date of the last modification in a comment.

The bash shell recognizes two different types of quotation marks, the single quote or aposotrophy, ', and the double quote, ". The two types of quotes are treated slightly differently. The single quote is called a strong quote; the double quote is called a weak quote. The shell interpolates variable in double quotes:

[ggeller@rop ~]$ echo "HISTSIZE is $HISTSIZE"
HISTSIZE is 1000

Interpolation means that the shell replaces the variable $HISTSIZE with the value that was set for it in /etc/profile. Single, or strong, quotes prevent interpolation:

[ggeller@rop ~]$ echo '$HISTSIZE ' "is $HISTSIZE"
$HISTSIZE  is 1000

Bash scripts can run in more than one way:

[ggeller@rop ~]$ source my_script.sh
hello world
[ggeller@rop ~]$ . my_script.sh
hello world
[ggeller@rop ~]$ chmod 755 my_script.sh
[ggeller@rop ~]$ ./my_script.sh
hello world

When you use the first two methods, source and ., the script is run in the same context as your shell. In the third method, we add executable permission to the script and invoke it like a command. In this case the bash shell actually launches a subshell, which is a new unix process when you run the command. Open my_script.sh in vi and change it so that it reads:

#!/bin/bash
ps

Run the ps command, then run my_script using each of the three methods shown:

[ggeller@rop ~]$ ps
  PID TTY          TIME CMD
11945 pts/2    00:00:00 bash
12123 pts/2    00:00:00 ps
[ggeller@rop ~]$ source my_script.sh
  PID TTY          TIME CMD
11945 pts/2    00:00:00 bash
12111 pts/2    00:00:00 ps
[ggeller@rop ~]$ . my_script.sh
  PID TTY          TIME CMD
11945 pts/2    00:00:00 bash
12112 pts/2    00:00:00 ps
[ggeller@rop ~]$ ./my_script.sh
  PID TTY          TIME CMD
11945 pts/2    00:00:00 bash
12113 pts/2    00:00:00 my_script.sh
12114 pts/2    00:00:00 ps

You can see that it runs as a seperate process in the third case.

The difference between a function and a script is that the function is syntax checked and loaded in memory. The script doesn't exist in memory.

The Script Command

The script command lets you record everything from a part of a session in a file called typescript:

[amellina@rop ~]$ script
Script started, file is typescript
[amellina@rop ~]$ ls -l /etc/init.d/functions 
-rwxr-xr-x 1 root root 11730 Feb 14  2006 /etc/init.d/functions
[amellina@rop ~]$ exit
exit
Script done, file is typescript

Then you can review you work with less, vi, or whatever.

Personal tools