Shell Programming


Changing Your Command-Line Prompt with PS



Yüklə 241,75 Kb.
səhifə4/4
tarix08.10.2017
ölçüsü241,75 Kb.
#3709
1   2   3   4

Changing Your Command-Line Prompt with PS

You can personalize your shell by changing the prompt your shell displays when it will accept commands. This is done by changing the value in the environment variable PS1. Suppose you wanted your command-line prompt to display your working directory. You could do this with:

$ PS1="'pwd'>"
/usr/home/teresa>cd /usr/home/john
/usr/home/teresa>

As you can see, you have changed the way your shell works. By writing your own shell programs and changing environment variables, you can create your own look. Notice though that the prompt does not change when you change directories. A function to do this is shown in the section "Adding Your Own Commands and Functions."



Adding Command-Line Separators with IFS

When a command line is entered in an interactive shell, each word on the command line is interpreted by the shell to see what action needs to be taken. By default, words are separated by spaces, tabs, and newline characters. You can add your own separators by changing the IFS environment variable, as in the following example:

$ IFS=':'
$ echo:Hello:My:Friend
Hello My Friend
$

Setting additional field separators does not void the default field separators; space, tab, and newline are always seen as field separators.



Checking Multiple Mailboxes with MAILPATH

Most users have only one mailbox for their electronic mail. Some users, however, may require multiple mailboxes (see Chapter 9, "Communicating with Others" for a discussion of electronic mail). For example, Dave wants to read mail addressed to him personally (which arrives to his personal user account), mail addressed to sysadm (which arrives to his system administrator account), and mail addressed to root (which arrives to his main account), but Dave can be logged in as only one of these accounts at any one time. Dave therefore can cause his current shell to check all three mailboxes by setting the environment variable MAILPATH, as follows:

$ MAILPATH="/usr/spool/mail/Dave:/usr/spool/mail/sysadm\
:/usr/spool/mail/root"

Now when mail is sent to any of these names, Dave receives the following message:

you have mail.

The only problem is that Dave does not know which mailbox to check when he receives this message. You can help solve Dave's problem by changing the mail message associated with each mailbox. You terminate the mailbox name in MAILPATH with a percent sign (%) and supply a message like this:

$ MAILPATH="/usr/spool/mail/Dave%Dave has mail\
:/usr/spool/mail/sysadm%sysadm has mail\
:/usr/spool/mail/root%root has mail

Automating Environment Changes

One problem with altering your environment by changing your environment variables is that when you log off, the changes are lost. You can give some permanence to your environment changes by placing the changes in your .profile.

Each time you log in to the Bourne shell, login looks in your home directory for the .profile file and executes the commands in that file. Any environment variables that you set and export in .profile are operative for subsequent operations, unless the user explicitly changes them.

But the .profile file can do more than just set environment variables, it is a shell program and can contain any of the commands that are valid in the Bourne shell.



Adding Your Own Commands and Functions

This chapter has shown how you can group UNIX commands together in files and create your own programs or shell scripts. Sometimes though, you don't achieve the desired results. The program in listing 11.13 changes the working directory, and at the same time changes the environment variable PS1, which contains the command-line prompt.



Listing 11.13. Change directory program chdir.

# Directory and Prompt Change Program


# Syntax: chdir directory
if [ ! -d "$1" ]
then
echo "$1 is not a directory"
exit 1
fi
cd $1
PS1="'pwd'> "
export PS1

When you execute the following chdir command from listing 11.13, nothing happens.

$ chdir /usr/home/teresa
$

There is no error message, yet the command-line prompt is not changed. The problem is that chdir is executed in a subshell, and the variable PS1 that was exported is made available only to lower shells. To make chdir work like you want, it must be executed within the current shell. The best way to do that is to make it a function. You can write the function in your .profile file, but there is a better solution. Group your personal functions into a single file and load them into your current shell using the transfer command (.). Rewrite chdir as a function, changing the exit to return. The function definition file persfuncs is shown in listing 11.14.



Listing 11.14. Personal function file with chdir written as a function.

#Personal function file persfuncs


chdir ()
{
# Directory and Prompt Change Program
# Syntax: chdir directory
if [ ! -d "$1" ]
then
echo "$1 is not a directory"
return
fi
cd $1
PS1="'pwd'> "
export PS1;
}
$ . persfuncs
$ chdir /usr/home/teresa
/usr/home/teresa> chdir /usr/home/john
/usr/home/john> _

Keeping personal functions in a separate file makes them easier to maintain and debug than keeping them in your .profile.

You can make your personal functions a permanent part of your environment by putting the command

.persfuncs

in your .profile.

Specialized Topics


Debugging Shell Programs

When you begin to write shell programs, you will realize something that computer users have known for years: programmers make mistakes! Sometimes what seems to be a perfectly reasonable use of computer language produces results that are unexpected. At those times, it is helpful to have some method of tracking down your errors.

The Bourne shell contains a trace option, which causes each command to be printed as it is executed, along with the actual value of the parameters it receives. You initiate the trace option by using set to turn on the -x option or execute a shell with the -x option. The sumints program is reproduced in listing 11.15.

Listing 11.15. An integer summing program.

# sumints - a program to sum a series of integers


#
if [ $# -eq 0 ]
then
echo "Usage: sumints integer list"
exit 1
fi
sum=0
until [ $# -eq 0 ]
do
sum='expr $sum + $1'
shift
done
echo $sum

Running sumints with the trace option looks like this:

$ sh -x sumints 2 3 4
+ [ 3 -eq 0 ]
+ sum=0
+ [ 3 -eq 0 ]
+ expr 0 + 2
+ sum= 2
+ shift
+ [ 2 -eq 0 ]
+ expr 2 + 3
+ sum= 5
+ shift
+ [ 1 -eq 0 ]
+ expr 5 + 4
+ sum= 9
+ [ 0 -eq 0 ]
+ echo 9
9
$

The trace shows you each command that executes and the value of any substitutions that were made before the command was executed. Notice that the control words if, then, and until were not printed.



Grouping Commands

Commands to a shell can be grouped to be executed as a unit. If you enclose the commands in parentheses, the commands are run in a subshell; if you group them in curly braces ({}), they are run in the current shell. The difference in the two has to do with the effect on shell variables. Commands run in a subshell do not affect the variables in the current shell, but if commands are grouped and run in the current shell, any changes made to variables in the group are made to variables in the current shell.

$ NUMBER=2
$ (A=2; B=2; NUMBER='expr $A + $B'; echo $NUMBER)
4
$ echo $NUMBER
2

In the previous example, note that the variable NUMBER had a value of 2 before the command group was executed. When the command group was run inside of parentheses, NUMBER was assigned a value of 4, but after execution of the command group was complete, NUMBER had returned to its original value. In this next example, when the commands are grouped inside of curly braces, NUMBER will keep the value it was assigned during execution of the command group.

$ {A=2; B=2; NUMBER='expr $A + $B'; echo $NUMBER}
4
$ echo $NUMBER
4
$

Note that the second example looks somewhat like a function definition. A function is a named group of commands, which executes in the current shell.



Using the Shell Layer Manager shl

UNIX is a multi-programming operating system. Some UNIX systems take advantage of this feature, allowing the user to open several shells at one time, which they can accomplish using the shell layer manager shl. Only the active layer can get terminal input, but output from all layers is displayed on the terminal, no matter which layer is active, unless layer output is blocked.



A layer is created and named with shl. While the user is working in a layer, he or she can activate the shell manager by using a special character (Ctrl+Z on some systems). The shell layer manager has a special command-line prompt (>>>) to distinguish it from the layers. While in the shell layer manager, the user can create, activate, and remove layers. Following are the shl commands:

create name

Creates a layer called name

delete name

Removes the layer called name

block name

Blocks output from name

unblock name

Removes the output block for name

resume name

Makes name the active layer

toggle

Resumes the most recent layer

name

Makes name the active layer

layers [-l] name ...

For each name in the list, displays the process ID. The -l option produces more detail.

help

Displays help on the shl commands

quit

Exits shl and all active layers


MAE
Yüklə 241,75 Kb.

Dostları ilə paylaş:
1   2   3   4




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©www.genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə