SHELL
- Shell – a built-in program that acts as an interface between user and system.
- Shell program – a series of UNIX commands, often referred as shell scripts.
- Shell functions – program execution, filename expansion, I/O redirection, piping facility, Interpretive programming language.
- Shell variable – a name associated with a value.
- System shell variables – variables which are defined by the system for its own use.
- User-defined shell variables – variables which are created by the user for its sake of convenience.
- Local shell variables – the variables which are defined inside a shell and available to its creator shell only.
- Global shell variables – the variables which are available to the child shells from its parent shell.
- Constant variables – the variables whose values can not be changed.
- Positional parameters – the built-in parameters which are used to receive arguments supplied at command prompt.
Bourne Shell
About this article i have studied in my class and i am saring with you about the concept of shell and shell programming language, one of the major assets of the UNIX operating system. The shell acts as an interface between the user and the operating system itself. As far as shell programming is concerned, it has most of the features that most high-level languages offer.
Like other high-level languages, the shell programming language has variables, conditional statements, control statements, functions and so on. If you already know any high-level language then it would be easy to understand shell-programming constructs. A shell program does not need any separate compiler for its execution. It is the shell that interprets the commands in the shell program and executes them. If a shell program consists of a series of UNIX commands then it is referred as shell script, a new horizon to computer world.
In a shell script, UNIX commands are used in slightly different fashion. Here UNIX commands are combined to perform some typical problems effectively. The shell script approach is usually more portable and simpler to implement making shell script an important tool of UNIX.
Firstly i am writing the various functions served by the shell.
Shell Functions
Shell performs various functions. Some of its important functions are as:
1. Program Execution
The shell interprets whatever we type on our terminal. If you have an empty command prompt $ then it means that the shell is waiting for you to type in a command. After typing a command and pressing Enter key, the shell interprets the line you have just typed in.
The first word of line is treated as the name of the command to be executed. And the remaining words are treated as argument(s), except for some special character. For example, in the following command
$ sort names > sorted_names
sort is the command name, and names and sorted_names are the arguments. Here the special characters is ‘>’, an output redirection operator. It is the shell who is responsible for ensuring that the arguments, you type in, get properly passed to the program being executed. After passing the arguments, the shell starts execution of the program. The shell displays the command prompt again after completing execution.
2. Filename Expansion
If the filename consists of some wildcard characters, such as *, ? or [..], the shell firstly performs the expansion and then execute the program. The details of these wildcard characters are discussed later on. At this point you need not to think more about it.
3. I/O Redirection
The shell also provides the facility of redirecting the input-output from standard input-output to a file. On input redirection, the shell receives the input from a file instead of a standard input, which is keyboard by default, by connecting it to the standard input of the program. Once again it happens just before the execution of the program. Here the poor program does not even know that its input has been redirected.
And in output redirection, the shell redirects the standard output to a file. If this file does not exist then it firstly creates it and then connect it to the program’s standard output. Like input redirection, the program does not know about output redirection; it just sends output to standard output in the normal way.
4. Piping Facility
The shell provides a pipe (|) to connect two programs. A pipe makes the output of one program to the input of another. And once again the shell takes the responsibility for connecting the standard output of the first program to the standard input of the second.
For example, in the following command
ls | wc –l
the output of ls command is input to wc command.
5. Interpretive Programming Language
The shell provides a powerful programming language that consists of variables, loops, conditional statements, files, and so on, just like any other programming language.
Types of Shells
There are three most widely used UNIX shells:
1. The Bourne Shell
2. The C Shell
3. The Korn Shell
All these three shell supports processes (both in foreground and in background), I/O redirection, pipes, filters, and some other commonly used facilities.
1. The Bourne Shell
Bourne shell gets its name from its inventor, Stephen Bourne. The Bourne shell is developed by Stephen Bourne of Bell Laboratories for Bell Labs releases of UNIX. The Bourne shell is the most powerful, and most widely used shell.
One of the main reason behind its popularity is that it is supplied with every UNIX system. Almost all UNIX vendors offer the Bourne Shell as part of their standard configuration. In this article Iwill discuss the Bourne shell in details.
2. The C Shell
C shell was developed at University of California at Berkeley by Bill Joy. C shell gets its name from its programming language, which resembles the C programming language in syntax. The C shell has an advanced user interface with enhanced features.
One of the main features of C shell is that it allows user to provide aliasing of commands. It means that instead of typing in lengthy commands, we can use short names for lengthy commands by using aliasing facility.
Another powerful feature of C shell is that it provides history feature, that is we can recall previously typed commands because UNIX system keeps track of all commands issued at the command line. You can easily recognize the C shell by seeing your prompt. The C shell offers a percent (%) sign as a command prompt.
3. Korn Shell
Like Bourne shell, the Korn shell was also developed at Bell Labs of AT&T. This shell gets its name from its inventor David Korn of Bell Labs. The Korn shell is one of the most modern shell available, and is likely become the industry standard. You can also say that the Korn shell is a superset of Bourne shell. Thus it offers more powerful and flexible features than Bourne shell.
Compatibility of Shells
The shells, which we have discussed in starting of the article, are the most commonly available shells on UNIX system. Each shell has its own merits and demerits. We can not use a shell script, written for one type of shell, with another type of shell. It is so because the programming of each shell is different. Furthermore the keywords, loops, conditional statements, and so on, may differ from shell to shell.
Since the Korn shell is compatible with Bourne shell, so all shell programs written for Bourne shell would work with Korn shell also. However the reverse is not true because Korn shell provides some advanced features such as arrays, command aliasing, and history commands which Bourne shell does not.
Here one should remember that C shell is not compatible with Bourne shell because its shell programming language is quite different from the language of the Bourne shell. Another difference between C shell and Bourne shell is that C shell, like Korn shell, provides aliasing and history commands which Bourne shell does not. The C shell also provides the better control over during the execution of background and foreground processes than that of Bourne shell.
However some more shells from other vendors of UNIX system are also available, such as vsh (visual shell), sysadmsh (system administrator), rsh (restricted shell), dsh (directory shell) and so many. In this article you would see the command languages provided in the standard Bourne shell.
Shell Variables
A shell variable is a name associated with a value. Like other programming languages. The shell provides the facility of defining and assigning values to shell variables. A shell variable name is any combination of alphabets, digits, and an underscore (_) that begins with an alphabet or an underscore.
Here is the list of some valid shell variable names.
names
length
height
_flag
add_to_420
On the other hand, the following names
6abc
simple interest
.principle
.area.2
24a
are the invalid shell variable names.
Shell variables are of two types:
1. System Shell Variables
2. User-defined Variables
System Shell Variables
The standard shell variables that are defined by the UNIX system for its own use are referred as system shell variables. These system shell variables are usually used by the system itself and their values are set by the shell. It is the user also who can change the values of these variables according to his needs and environment.
One can easily check the values of system shell variables by just typing set as:
$ set
HOME=/usr/amit
IFS=
LOGNAME=amit
MAIL=/usr/mail/amit
MAILCHECK=600
PATH=:/bin:/usr/bin:.
PS1=$
PS2=>
SHELL=/bin/sh
TERM=adma
$
The set command displays the system shell variables along with their values. The name to the left of each equal sign is the name of system shell variable. It is not necessary that you will have the exact set of variables that we have here. Your system may add to or subtract from this list of system shell variables.
Let us briefly define their meaning.
HOME: It stores the default working directory of the user.
IFS (Internal Field Separator): It is used to provide the list character to separate words in a command line. It may be a space, a tab or a newline. If it is set to newline, it provides a blank line following IFS.
LOGNAME: It defines the path of the directories which the shell checks whether the user has received any mail.
PATH: It defines the path of the directories which the shell search to execute any command or file. A colon is used to separate the directory names. The directory is searched in the order given. For example, if we type a command and then press Enter, the shell first searches /bin directory by that command and name. If it does not find that command there, it looks in /usr/bin directory. If it still has not found then command, it looks in user’s current directory(.). And if it still is unable to find that file, the shell reports an error message that it can’t find that command.
PS1 (Prompt String): It stores the symbol used as your prompt. Generally it is set to “$”. If you want the prompt to be something else other than the $, then the command
$ PS1=“++”
resets the prompt to a “++”
PS2 (Prompt String 2) : It stores the second prompt of your system. Its default value is “>”. This prompt is used when you start a new line without finishing a command. For example, let you type something and put a backslash (\) before pressing Enter key as:
$ echo It is my good luck and \
> your bad luck.
It is my good luck and your bad luck.
$
SHELL: It defines the name of your default working shell.
TERM: It defines the kind of terminal on which you are working.
User-defined Shell Variable
A user-defined shell variable is created by the user for its sake of convenience. User-defined shell variables can be of any reasonable length. A user-defined shell variable name is any combination of alphabets, digits, and an underscore (_) that begins with an alphabet or an underscore.
When we create a shell variable and assign some value to it, we follow the following form as:
shell_variable=value
The left hand side of equal (=) sign is the name of newly created shell variable name and the right hand side of it is the value associated with this variable name.
For example,
$number=20
creates a shell variable having the name number, and assigns a value “20” to it. Here the “20” is not treated as a number, rather than it is treated as a string consisting of the digit characters “2” and “0”. You can also store a series of characters in shell variables as:
$ name=Sultan
If you want to display the value of a shell variable then you should use the echo command as:
$ echo $number
20
$ echo $name
Sultan
$
The symbol $ preceded by an argument to echo displays the value of the shell variable. As stated earlier, if you omit $ then number and name are treated as simple argument as:
$ echo $number
number
$ echo $name
name
$
If you want to carry out more than one assignment in a line, you do as:
$ name=Sultan number=20
$ echo $name $number
Sultan 20
$
We can use both variable’s name and its value in the same echo statement.
$ name=Sagar
$ echo My name is $name.
My name is Sagar.
$
If a variable’s value contains more than one word then it is necessary to enclosed in double quotes as:
$ name=“Shrey Sagar”
$ echo My name is $name.
My name is Shrey Sagar.
$
Now let us examine the output when we assign no value to the varaible name.
$ name=“ ”
$ name=‘ ’
$ name=
All these three variables are assigned no values or you can say it a null string. When we echo a null variable, only a blank line appears on the screen as:
$ echo $name
$
Like system shell variables, user-defined shell variables are also displayed using the set command.
Local and Global Shell Variables
All the variables defined inside a shell are referred as local shell variables. These local variables are known only to the shell that created it. If you have a variable name, say num, then this variable, num, is unknown to the new shell, if created, because num is local to the older shell and each shell’s variable are local (private) to itself.
$ name=Ati
$ echo $name
Ati
$ sh
$ echo $name
$ name=Shrestha
$ echo $name
Shrestha
$ Ctrl – d
$ echo $name
Ati
$
Here name was defined in the parent (older) shell, therefore it does not hold any value in the subshell (new shell). If you want to persist the older shell variables to the new shell then you must use export command.
The export Command
The export command makes any shell variable to be global to all shells descending from the current shell. It means that the exported variable remains export to all sub-shell that are subsequently executed.
We use the export command as:
$ export num
$ num=20
$ echo $num
20
$ sh
$ echo $num
20
$ num=10
$ echo num
10
$ echo Ctrl – d
$ echo num
20
$
We can also first create the variable and then export it as:
$ num=20
$ export num
One should note here that even exported variables are not completely global because they are exported to child shells, not back to a parent shell. It happens so because when a new shell is created, the current shell provides a copy of the original shell along with its value. If we make any change to the exported variable in the new shell then its value is changed in the new shell only. Thus when this new shell terminates, the copy of exported variable to this shell also dies. And the original variable remains unchanged.
If you want to obtain a list of all exported variables either in parent shell or in any sub-shell, then just type export without any argument as:
$ export
After the execution of this command, you get a list of all exported variables along with their values. This list would contain only those variables which are exported by the current shell and would not contain those that may have been inherited from the parent shell.
Now watch carefully the behavior of an exported variable, num in following scenario.
$ num=10
$ export num
$ echo $num
10
$ sh sub-shell
$ echo $num
10
$ num=20
$ echo $num
20
$ sh sub-sub-shell
$ echo $num
10
$ num=30
$ echo $num
30
$ sh sub-sub-sub-shell
$ echo $num
10
$ Ctrl – d terminating sub-sub-sub-shell
$ echo $num
30
$ Ctrl – d terminating sub-sub-shell
$ echo $num
20
$ Ctrl – d terminating sub-shell
$ echo $num
10
$
If you modify an exported variable in a sub-shell and you want this modified value in sub-sub-shell, then you must once again export the variable in sub-shells as:
$ export num
$ num=10
$ echo $num
10
$ sh sub-shell
$ num=20
$ export num
$ sh sub-sub-shell
$ echo $num
20
$ sh sub-sub-sub-shell
$ echo $num
20
$
Constant Variables
Constant variables are those whose values can not be changed. The shell variables are made constant variables by list all such variables readonly at the command prompt as:
$ num=20
$ readonly num
$
After declaring a shell variable as a readonly, the shell does not allow us to change its value.
Removing Variables
After a variable serves its purpose, it is good idea to remove it. A variable is removed by using the unset command. For example, the following command
$ unset num
removes the variable num and its value from shell’s memory. Note that the shell does not allow user to use unset command on system shell variables.
Positional Parameters
The shell scripts that we have seen so far offers argument from the keyboard. Like most UNIX commands, the shell script can also take arguments supplied at the command line. The shell provides positional parameters by which the shell scripts know what has been passed to it?
Within the script, the first argument is referred as $1, the second argument as $2, and so on. These arguments are referred as positional parameters. Positional parameters are nine in numbers, named $1, $2, $3, …. , $9. In addition, $0 is used to refer the name of the command itself.
For example, let you execute a shell script players along with its argument as:
$ players Sachin is the great player of world cricket.
Here the first argument, Sachin, is assigned to $1, second argument, is, to $2, third argument, the, to $3, and son on. The eighth argument, cricket, is assigned to $8. The shell program, players, would treat these arguments like any other shell variables. For instance, if you want to display the value of first and fourth argument, you use the echo command as:
$ echo $1 $4
Sachin great
$
If you want to display the value of all eight arguments, you use the following command:
$ echo $1 $2 $3 $4 $5 $6 $7 $8
Sachin is the great player of world cricket.
$
Since we know that the positional parameters are treated as like any other shell variables, but like user-defined shell variables and system shell variables, you can’t assign values to $1, $2, …. etc. as $1=20 or $2=Rahul. The positional parameters are set up either by command line argument, that we have seen so far, or by using the set command as:
$ set I think I am not the only fool.
This set command sets the value $1 to ‘I’, $2 to ‘think’, $3 to ‘I’, and so on. You can use the echo command to verify it as:
$ echo $1 $2 $3 $4 $5 $6 $7 $8
I think I am not the only fool.
$
If you use two or more set commands then the positional parameters will contain the latest values of $1, $2, etc., rather than the old values. Following set of statements would make this concept clear.
$ set You are not the great cricketer on this earth.
$ echo $1 $2 $3 $4 $5 $6 $7 $8 $9
You are not the great cricketer on this earth.
$ set Sachin Tendulkar is the great player on this earth.
$ echo $1 $2 $3 $4 $5 $6 $7 $8 $9
Sachin Tendulkar is the great player on this earth.
$
If you want to save the older contents of positional parameters then it is better idea to save the older contents in user-defined shell variables as:
$ set one two three
$ first=$1 second=$2 third=$3
$ set four five six
$ echo first second third $1 $2 $3
one two three four five six
$
Thus the set command produces a list of all current shell variables and their values. The set command is very useful when it is used in conjunction with command substitution. When we use a command with the set command then it is mandatory to enclosed it with the metacharacters ‘ ‘. When a command is enclosed in back quotes, it is replaced by the output this command produces. This process is called as command substitution.
For example,
$ set ‘who am i‘
$ echo $1 $2 $3 $4 $5
amit tty4 Oct 11 07:10
$
Here the command ‘who am i‘ is replaced by its output and amit is assigned to $1, tty4 to $2, and so on. If you do not used back quotes the then output would be different as:
$ set who am i
$ echo $1 $2 $3
$ who am i
$
Thus if you do not use the back quotes then the who am i is treated as simple positional parameters and who is assigned to $1, am to $2 and i to $3. Now the question arises – what happens when your command line provides more than nine arguments? The output of following command would clear your concept.
$ set It is very difficult to live in this world without any tension.
$ echo $1 $2 $3
It is very
$ echo $1 $2 $3 $4 $5 $6
It is very difficult to live
$ echo $1 $2 $3 $4 $5 $6 $7 $8 $9
It is very difficult to live in this world
$ echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12
It is very difficult to live in this world It0 It1 It2
There is no doubt in the output of first three echo statements. But look at the output of last echo statement. This output is so strange because we have only nine positional parameters. So if we try to refer to $10, it is interpreted as $1 and a 0. That’s why we got It0 in the output. Similarly $11 and $12 are treated as $1-1 and $1-2 respectively.
Now one may ask you that how would you get these remaining words. There are two options to achieve this – either by using the shift command or by using the special notation $*. The $* stands for all the positional parameters from $1 to $9, also including those beyond $9.
Thus if you use the following echo command
$ echo $*
then it would display all the positional parameters. The $* collects the positional parameters collectively but not individually.
For example,
$ set It is very difficult to live in this world without any tension.
$ echo $*
It is very difficult to live in this world without any tension.
$
The shell provides another special notation, $#, in order to represent the total number of arguments. The following example makes use of both $* and $#.
Let we place the following statements in the file sscript5 as:
# sscript5
# Usage: sscript5 list_of_arguments
echo Total number of arguments are $#
echo Arguments are as $*
If you execute this script by making it executable initially then the output is as:
$ sscript5 It is nice to have a friend like you.
Total number of arguments are 9
Arguments are as It is nice to have a friend like you.
$
After applying shift command, we lost first three arguments forever. That’s why it is necessary to store these arguments prior to use of shift command. We can also use both $* and shift command in one script as:
# sscript6
# Usage: sscript6 list_of_arguments
echo $*
shift 1
echo $*
shift 2
echo $*
shift 3
echo $*
shift
echo $*
when you execute this script6, you will get the following output….
$ sscript6 A gem is not polished without rubbing it.
A gem is not polished without rubbing it.
gem is not polished without rubbing it.
not polished without rubbing it.
rubbing it.
it.
$
If you do not specify the number of arguments to be shifted, as in last case, it takes 1 parameter by default.
Arithmetic Operations with Shell Variables
Like other programming languages, the shell does not provide any built-in mechanism to perform operations on shell variables. Perhaps it may be so because all shell variables are treated as string variables. Keep it in mind that without arithmetic operations, there is no life of shell programmer. The shell provides the expr command to evaluate arithmetic expressions in shell programs.
Let us look at some simple examples using expr command.
$ expr 14 + 8
22
$ expr 12 – 8
4
$ expr 4 \* 2
8
$ expr 14 / 3
4
$ expr 14 % 3
2
$