Working with Shell



In this section we will play with shell.

Shell is an interface between a user and the kernel. It is a command interpreter which interprets the commands entered by user and sends to kernel. 


The Solaris shell supports three primary shells:
Bourne Shell:
It is original UNIX system shell.
It is default shell for root user.
The default shell prompt for the regular user is $ and root is #.
C Shell:
It has several features which bourne shell do not have. 
The features are:
It has command-line history, aliasing, and job control.
The shell prompt for regular user is hostname% and for root user hostname#.
Korn Shell:
It is a superset of Bourne Shell with C shell like enhancements and additional features like command history, command line editing, aliasing & job control. 

Alternative shells:
Bash(Bourne Again shell): It is Bourne compatible shell that incorporates useful features from Korn and C shells, such as command line history and editing and aliasing.
Z Shell: It resembles Korn shell and includes several enhancements.
TC Shell: It is completely compatible version of C shell with additional enhancements.

Shell Metacharacters:
Lets understand Shell Metacharacters before we can proceed any further.  These are the special characters, generally symbols that has specific meaning to the shell.There are three types of metacharacters:
1. Pathname metacharacter
2. File name substitution metacharacter
3. Redirection metacharacter

Path Name Metacharacters:
Tilde (~) character: The '~' represents the home directory of the currently logged in user.It can be used instead of the user's absolute home path.Example : Lets consider ravi is the currently logged in user.
#pwd
/
#cd ~
#pwd
/export/home/ravi
#cd ~/dir1
#pwd
/export/home/ravi/dir1
#cd ~raju
#pwd
/export/home/raju
Note: '~' is available in all shells except Bourne shell.

Dash(-) character: The '-' character represents the previous working directory.It can be used to switch between the previous and current working directory. 

Example:
#pwd
/
#cd ~
#pwd
/export/home/ravi
#cd -
#pwd
/
#cd -
#pwd
/export/home/ravi

File Name Substitution Metacharacters :
Asterisk (*) Character: It is a called wild card character and represents zero or more characters except for leading period '.' of a hidden file.
#pwd
/export/home/ravi
#ls dir*
dir1 dir2 directory1 directory2
#
Question Mark (?) Metacharacters: It is also a wild  card character and represents any single character except the leading period (.) of a hidden file.
#pwd
/export/home/ravi
#ls dir?
dir1 dir2
#
Compare the examples of Asterisk and Question mark metacharacter and you will get to know the difference.


Square Bracket Metacharacters: It represents a set or range of characters for a single character position. 
The range list can be anything like : [0-9], [a-z], [A-Z].
#ls [a-d]*
apple boy cat dog
#
The above example will list all the files/directories starting with either 'a' or 'b' or 'c' or 'd'.
#ls [di]*
dir1 dir2 india ice
#
The above example will list all the files starting with either 'd' or 'i'. 


Few shell metacharacters are listed below:  
Metacharacter
Description
~ The '~' represents the home directory of the currently logged in user
- The '-' character represents the previous working directory
* A wild card character that matches any group of characters of any length
? A wild card character that matches any single character
$ Indicates that the following text is the name of a shell (environment) variable whose value is to be used
| Separates command to form a pipe and redirects the o/p of one command as the input to another
< Redirect the standard input
> Redirect the standard output to replace current contents
>> Redirect the standard output to append to current contents
; Separates sequences of commands (or pipes) that are on one line
\ Used to "quote" the following metacharacter so it is treated as a plain character, as in \*
& Place a process into the background


Korn Shell Variables: It is referred to as temporary storage area in memory.It enables us to store value into the variable. These variables are of two types :
1. Variables that are exported to subprocesses.
2. Variables that are not exported to subprocesses.


Lets check few commands to work with these variables:
To set a variable 

#VAR=value
#export VAR
Note: There is no space on the either side of the '=' sign.


To unset a variable

#unset VAR

To display all variables:  

We can use 'set' or 'env' or 'export' command.

To display value of a variable

echo $VAR or print $VAR
Note: When a shell variable follows $ sign, then the shell substitutes it by the value of the variable.

Default Korn Shell Variables :
EDITOR : The default editor for the shell.
FCEDIT : It defines the editor for the fc command.
HOME : Sets the directory to which cd command switches.
LOGNAME : Sets the login name of the user.
PATH : It specifies the paths where shell searches for a command to be executed.
PS1 :It specifies the primary korn shell ($)
PS2 : It specifies the secondary command prompt (>)
SHELL : It specifies the name of the shell.


Using quoting characters:
Quoting is the process that instructs the shell to mask/ignore the special meaning of the metacharacters. Following are few use of the quoting characters:

Single quotation mark (''): It instructs the shell to ignore all enclosed metacharacters.
Example:
#echo $SHELL
/bin/ksh
#echo '$SHELL'
$SHELL
#
Double quotation mark (""): It instructs the shell to ignore all enclosed shell metacharacters, except for following :
1. The single backward quotation(`) mark : This executes the solaris command inside the single quotation.
Example: 
# echo "Your current working directory is `pwd`"
Your current working directory is /export/home/ravi
In the above example the '`' is used to execute the 'pwd' command inside the quotation mark.

2. The blackslash(\) in the front of a metacharacter : This ignores the meaning of the metacharacter.
Example: 
#echo "$SHELL"
/bin/ksh
#echo "\$SHELL"
$SHELL
In the above example, the inclusion of '\' ignores the meaning of metacharacter '$'

3. The '$' sign followed by command inside parenthesis : This executes the command inside the parenthesis.
Example: 
# echo "Your current working directory is $(pwd)"
Your current working directory is /export/home/ravi


In the above example enclosing the pwd command inside parenthesis and $ sign before parenthesis, executes the pwd command.

Displaying the command history:
The shell keeps the history of all the commands entered. We can re-use this command in our ways. For a given user this list of command used is shared among all the korn shells.
Syntax: history option
The output will somewhat like following :
...
125 pwd
126 date
127 uname -a
128 cd
The numbers displayed on the left of the command are command numbers and can be used to re-execute the command corresponding to it.
To view the history without command number -n option is used : #history -n
To display the last 5 commands used along with the current command : 
#history -5
To display the list in reverse order: 
#history -r
To display most recent pwd command to the most recent uptime command, enter the following:
#history pwd uptime

Note: The Korn shell stores the command history in file specified by the HISTFILE variable. The default is the ~/.sh_history file. By default shell stores most recent 128 commands.

Note: The history command is alias for the command "fc -l".

The 'r' command :
The r command is an alias in Korn Shell that enables us to repeat a command.
Example:
#pwd
/export/home/ravi
#r
/export/home/ravi

This can be used to re-execute the commands from history.

Example:
#history
...
126 pwd
127 cd
128 uname -a
#r 126
/export/home/ravi

The 'r' command can also be used to re-execute a command beginning with a particular character, or string of characters. Example:
# r p
pwd
/export/home/ravi
#
In the above example the 'r' command is used to re-run the most recent occurrence of the command starting with p.

#r ps
ps -ef
o/p of ps -ef command
In the above example the 'r' command is used to re-run the most recent command starting with ps.

We can also edit the previously run command according to our use. The following example shows that :
#r c
cd ~/dir1
#r dir1=dir
cd ~/dir
In this example the cd command has re-run but the argument passed to it has been changed to dir from dir1.


Note: The r command is alias for the command " fc -e - ".

Editing the previously executed commands using vi-editor :
We can also edit the previously executed command under history using vi-editor. To do so, we need to enable shell history editing by using any one of the following commands :
#set -o vi
or
#export EDITOR=/bin/vi
or
#export VISUAL=/bin/vi


To verify whether this feature is turned on, use the following command :
#set -o | grep -w vi
vi                on


Once it is on you can start editing the command history as follows :
1. Execute the history command: #history
2. Press Esc key and start using the vi editing options.
3. To run a modified command, press enter/return key.

File Name Completion : 
Suppose you are trying to list files under the directory "/directoryforlisting". This is too big to type. There is a short method to list this directory. 

Type ls d and then press Esc and then \ (backslash) key. The shell completes the file name and will display :
#ls directoryforlisting/


We can also request to display all the file name beginning with 'd' by pressing Esc and = key sequentially.


Two points to be noted here :
1. The key sequence presented above works only in the vi mode of the command line editing.
2. The sequence in which the key is pressed is important.

Command Redirection:
There are two redirection commands:
1. The greater than (>) sign metacharacter
2. The less than (<) sign metacharacter
Both the above mentioned mentioned commands are implied by pipe (|) character.

The File Descriptors:
Each process works with shell descriptor. The file descriptor determines where the input to command originates and where the output and error messages are sent.
File Descriptor Number
File Description Abbreviation
Definition
0 stdin Standard Command input
1 stdout Standard Command output
2 stderr Standard Command error

All command that process file content read from the standard input and write to standard output.

Redirecting the standard Input:
command < filename or command 0<filename
The above command the "command" takes the input from "filename" instead of keyboard.

Redirecting the standard Output:
command > filename or command 1>filename
#ls -l ~/dir1 > dirlist
The above command redirects the output to a file 'dirlist' instead of displaying it over the terminal.
command >> filename
#ls -l ~/dir1 >> dirlist
The above example appends the output to the file 'dirlist'.

Redirecting the Standard Error:
command > filename 2> <filename that will save error>
command> filename 2>&1
The first example will redirect the error to the file name specified at the end. 

The second example will redirect the error to the input file itself.

The Pipe character :
The pipe character is used to redirect the output of a command as input to the another command.
Syntax: command | command

Example:
# ps -ef | grep nfsd
In the above example the output of ps -ef command is send as input to grep command.
#who | wc -l

User Initialization Files Administration :
In this section we will see initialization files of Bourne, Korn and C shell.
Initialization files at Login
/bin/ksh
Shell
System wide Initialization File
Primary user Initialization File Read at Login
User Initialization Files Read When a New Shell is Started
Shell Pathname
Bourne/etc/profile$HOME/.profile /bin/sh
Korn /etc/profile $HOME/.profile $HOME/.kshrc /bin/ksh
$HOME/.kshrc
C /etc/.login $HOME/.cshrc $HOME/.cshrc /bin/csh
$HOME/.login

Bourne Shell Initialization file:
The .profile file in the user home directory is an initialization file which which shell executes when the user logs in. It can be used to a) customize the terminal settings & environment variables b)instruct system to initiate an application.

Korn Shell Initialization file: It has two initialization file :
1. The ~/.profile: The .profile file in the user home directory is an initialization file which which shell executes when the user logs in. It can be used to a) customize the terminal settings & environment variables b)instruct system to initiate an application.
2. The ~/.kshrc: It contains shell variables and aliases. The system executes it every time the user logs in and when a ksh sub-shell is started. It is used to define Korn shell specific settings. To use this file ENV variable must be defined in .profile file.


Following settings can be configured in /.kshrc file :
Shell prompt definations (PS1 & PS2)
Alias Definitions
Shell functions
History Variables
Shell option ( set -o option)
The changes made in these files are applicable only when the user logs in again. To make the changes effective immediately, source the ~/.profile and ~/.kshrc file using the dot(.) command:
#. ~/.profile
#. ~/.kshrc
Note: The /etc/profile file is a separate system wide file that system administrator maintains to set up tasks for every user who logs in.

Shell Initialization file: It has two initialization file :
1. The ~/.cshrc file : The . cshrc file in the user home directory is an initialization file which which shell executes when the user logs in. It can be used to a) customize the terminal settings & environment variables b)instruct system to initiate an application.
Following settings can be configured in .cshrc file :
Shell prompt definations (PS1 & PS2)
Alias Definitions
Shell functions
History Variables
Shell option ( set -o option) 


2. The ~/.login file: It has same functionality as .cshrc file and has been retained for legacy reasons.
Note: The /etc/.login file is a separate system wide file that system administrator maintains to set up tasks for every user who logs in.

The changes made in these files are applicable only when the user logs in again. To make the changes effective immediately, source the ~/.cshrc and ~/.login file using the source command:
#source ~/.cshrc
#source ~/.login

The ~/.dtprofile file : It resides in the user home directory and determines generic and customized settings for the desktop environment.The variable setting in this file can overwrite the default desktop settings. This file is created when the user first time logs into the desktop environment. 

Important: When a user logins to the desktop environment, the shell reads .dtprofile, .profile and .kshrsc file sequentially. If the DTSOURCEPROFILE variable under .dtprofle is not ture or does not exists, the .profile file is not read by the shell.
The shell reads .profile and .kshrsc file when user opens console window.
The shell reads .kshrsc file when user opens terminal window.

Configuring the $HOME/.profile file:
It can be configured to instruct the login process to execute the initialization file referenced by ENV variable.
To configure that we need to add the following into the $HOME/.profile file:
ENV=$HOME/.kshrc
export ENV

Configuring the $HOME/.kshrc file :
This file contains korn shell specific setting.To configure PS1 variable, we need to add the following into the $HOME/.kshrc file:
PS1="''hostname' $"
export PS1

Advanced Shell Functionality:
In this module we will learn four important aspects of Korn shell.


Managing Jobs in  Korn  Shell:
A job is a process that the shell can manage. Each job has a process id and it can be managed and controlled from the shell.
The following table illustrates the job control commands:
Command
Value
jobsList all jobs that are currently running or stopped in the background
bg %<jobID>Runs the specified job in background
fg %<jobID>Brings the  specified job in foreground
Ctrl+ZStops the foreground job and places it in the background as a stopped job
stop %<jobID>Stops a job running in background

Note: When a job is placed either in foreground or background, the job restarts.

Alias Utility in Korn Shell :

Aliases in Korn shell can be used to abbreviate the commands for the ease of usage. 

Example:
we are frequently using the listing command: ls -ltr. We can create alias for this command as follows:
#alias list='ls -ltr'
Now when we type the 'list' over shell prompt and hit return, it replaces the 'list' with the command 'ls -ltr' and executes it.
Syntax : alias <alias name>='command string'
Note: 
1. There should not be any space on the either side of the '=' sign. 
2. The command string mustbe quoted if it includes any options, metacharacters, or spaces.
3. Each command in a single alias must be separated with a semicolon.e.g.:#alias info='uname -a; date'

The Korn shell has predefines aliases as well which can be listed by using 'alias' command:

#alias
..
stop='kill -STOP'
suspend='kill -STOP $$'
..
Removing Aliases
Syntax: unalias <alias name>
Example:
#unalias list

Korn Shell functions :

Function is a group of commands organized together as a separate routine. Using a function involves two steps :


1. Define the function: 
function <function name> { command;...command; }
A space must appear after the first brace and before the       closing brace. 
Example:
#function HighFS{ du -ak| sort -n| tail -10; } 
The above example defines a function to check the top 10 files using most of the space under current working directory.   

2. Invoke the function :

If we want to run the above defined function, we just need to call it by its name.
Example:
#HighFS
6264    ./VRTSvcs/conf/config
6411    ./VRTSvcs/conf
6510    ./VRTSvcs
11312   ./gconf/schemas
14079   ./gconf/gconf.xml.defaults/schemas/apps
16740   ./gconf/gconf.xml.defaults/schemas
17534   ./gconf/gconf.xml.defaults
28851   ./gconf
40224   ./svc
87835   .
Note: If a function and an alias are defined by the same name, alias takes precedence.

To view the list of all functions :

#typeset -f -> This will display functions as well as their definitions.
#typeset +f -> This will display functions name only.

Configuring the Shell Environment variable:


The shell secondary prompt sting is stored in the PS2 shell variable, and it can be customized as follows:

#PS2="Secondary Shell Prompt"
#echo PS2
Secondary Shell Prompt
#
To display the secondary shell prompt in every shell, it must be included in the user's Korn Shell initialization file(.kshrc file)

Setting Korn Shell options :
Korn Shell options are boolean (on or off). Following is the Syntax:
To turn on an option:
#set -o option_name

To turn off an option:
#set +o option_name


To display current options:
# set -o 

Example:
#set -o noclobber
#set -o | grep noclobber
noclobber      on

The above example sets the noclobber option. When this option is set, shell refuses to redirect the standard output to a file and displays error message on the screen.

#df -h > DiskUsage

#vmstat > DiskUsage
ksh: DiskUsage: file already exists
#
To deactivate the noclobber option :
#set +o noclobber


Shell Scripts:
It is a text file that has series of command executed one by one. There are different shell available in Solaris. To ensure that the correct shell is used to run the script, it should begin with the characters #! followed immediately by the absolute pathname of the shell.
#!/full_Pathname_of_Shell
Example: 
#!/bin/sh 
#!/bin/ksh

Comments: It provides information about the script files/commands. The text inside the comment is not executed. The comment starts with character '#'.

lets write our first shell script :
#cat MyFirstScript
#!/bin/sh
ls -ltr #This is used to list the files/directories

Running a Shell Script :
The shell executes the script line by line. It does not compile the script and keep it in binary form. So, In order to run a script, a user must have read and execute permission.
Example: 
#./MyFirstScript
The above example runs the script in sub-shell. If we want to run the script as if the commands in it were ran in same shell, the dot(.) command is used as follows:
#. ./MyFirstScript

Passing Value to the shell script:

We can pass value to the shell script using the pre-defined variables $1, $2 and so on. These variables are called Positional Parameters. When the user run the shell script, the first word after the script name is stored in $1, second in $2 and so on.
Example:
#cat welcome
#!/bin/sh
echo $1 $2
#welcome ravi ranjan
ravi ranjan

In the above example when we ran the script welcome, the two words after it ravi and ranjan was stored in $1 and $2 respectively.


Note: There is a limitation in Bourne shell. It accepts only a single number after $ sign. So if we are trying to access the 10th argument $10, it will result in the value of $1 followed by (0).

In order to overcome this problem, shift command is used.

Shift Command:
It enables to shift the value of positional parameter values back by one position i.e. the value of $2 parameter is assigned to $1, and $3 to $2, and so on.

Checking Exit status:

All commands under Solaris returns an exit status. The value '0' indicates success and non-zero value ranging from 1-255 represents failure. The exit status of the last command run under foreground is held in ? special shell variable.

# ps -ef | grep nfsd
    root  6525 22601   0 05:55:01 pts/11      0:00 grep nfsd
# echo ?
1

In the above example there is no nfsd process running, hence 1 is returned. 



Using the test Command:
It is used for testing conditions. It can be used to verify many conditions, including:
Variable contents
File Access permissions
File types
Syntax : #test expression or #[ expression ]

The test builtin command returns 0 (True) or 1 (False), depending on the evaluation of an expression, expr. 
Syntax:test expr or [ expr ]

We can examine the return value by displaying $?; 
We can use the return value with && and ||; or we can test it using the various conditional constructs.


We can compare arithmetic values using one of the following:
OptionTests for Arithmetical Values
-eqequal to
-nenot equal to
-ltless than
-leless than or equal to
-gtgreater than
-gegreater than or equal to

We can compare strings for equality, inequality etc. Following table lists the various options that can be used to compare strings:



Option
Tests for strings
=equal to. 
e.g #test "string1" = "string2"
!= not equal to.  
e.g #test "string1" = "string2"
 < less than.  
e.g #test "ab" \< "cd"
> greater than.  
e.g #test  "ab" \> "cd" "
-z for a null string.  
e.g #test -z "string1" 
-n returns True if a string is not empty. 
e.g. #test -n "string1"

Note: the < and > operators are also used by the shell for redirection, so we must escape them using \< or \>. 


Example : 

Lets test that the value of variable $LOGNAME is ravi.
#echo $LOGNAME
ravi
# test "LOGNAME" = "ravi"
#echo $?
0

#[ "LOGNAME" = "ravi" ]
#echo $?
0

Lets test if read permissions on the /ravi
#ls -l /ravi
-rw-r--r-- 1 root sys 290 Jan 10 01:10 /ravi
#test -r /ravi
#echo $?
0

#[ -r /ravi ]
#echo $?
0

Lets test if /var is a directory
#test -d /var
#echo $?
0

#[ -d /var ]
#echo $?
0




Executing Conditional Commands
In this section we will see the following three conditional commands:
1. Using If command: It checks for the exit status of the command and if exist status is (0), then the statement are run other wise statement under else is executed.
Syntax:
#if command1
>then
>execute command2
>else
>execute command3
>fi

The shell also provides two constructs that enable us to run the command based on the success or failure of the preceding command.
The constructs are &&(and) and ||(or).
Example:
#mkdir /ravi && /raju 
This command creates directory /raju only if /ravi is created.

#mkdir /ravi || /raju
This command creates directory /raju even if /ravi fails to create.

2. Using while command: It enables to repeat a command or group of command till the condition returns (0).

Syntax:
#while command1
>do
>command2
>done

3. Using case command: It compares a single value against other values and runs a command or commands when a match is found.

Syntax:
#case value in
>pat1)command
>command
>..
>command
>;;

>pat2)command
>command
>..
>command
>;;
...

>patn)command
>command
>..
>command

The special shell variable :

? This contains the return value of the last command
# This contains the number of arguments passed to the script
* It contains the value of all command line argument



No comments:

Post a Comment