Вы находитесь на странице: 1из 15

What is a shell?

One of the most powerful program available in UNIX


Provide consistent and easy to use environment for executing programs
It reads the command you type and and ask UNIX kernel to perform these
commands
Provides sophisticated programming constructs

A shell is a program that reads commands and executes them. Another name for a
shell is a command interpreter.

Current Unix shells, such as bash, ksh, and tcsh, provide numerous conveniences
and features for both interactive and programmatic purposes and are complicated
programs in their own right.

There are as many as 30+ Unix shells, but the most popular are sh, ksh, bash, csh
and tcsh.

Interactive versus scripts

When you manually type commands to the shell, you are running an interactive
shell. The shell features beneficial for interactive use are different from those needed
when running a script, in which the shell reads commands from a file.
In interactive use, shell features that minimize typing and tedium are important. For
scripting or programmatic use, flexibility, power and expressiveness are more
important.

In this perspective shell script is a text file containing group of UNIX


commands, shell built-in commands, control structures to do certain work.

Executing a shell script

In order to execute a file containing a shell commands the file should have the
execute permission.

chmod a+rx myshellscript

Then it can be executed using the following methods:

sh myshellscript
./myshellscript

Note: If you are executing a script using sh then you need not to give execute
permission to shell script.

To execute the script inside the current shell (without forking) useful to load
environment variables in the current shell do:

. myshellscript
You may optionally specify the pathname of your shell interpreter in this case the
very first line of the shell script must contain a pound sign (#) in the first column
and an exclamation point in the second (!) followed by the pathname of the sh
executable.

#!/bin/sh

This notation is used by the system to determine which command interpreter should
be used to execute the file content.

Reading input

Reading from the terminal can be accomplish with the following syntax:

read myinput

Example:

echo "Enter your input: "


read answer
echo "Your input is $answer"

Back tick expansion or command substitution

When we put any command in back quotes like`command` (we use back quotes not
the normal forward quotes), then it is replaced by the output of the command.
Typically command only produces one line of output. For example the basename
PATH command strips off any directory portion of path, so to get the file name in a
script you usually see:

fff=/usr/share/timezone/Pacific.tz
filepart=`basename $fff` # filepart=Pacific.tz

Numeric variables

The expr command is used to perform mathematical operations. The following


operators can be used with the expr command:

Operator Description
% Remainder of division
/ Divide
\* Multiply
+ Add
- Subtract

Operator Description
= Integer comparison (equal).
\> Integer comparison (greather).
\>= Integer comparison (greather or equal).
\< Integer comparison (less than).
\<= Integer comparison (less than or equal).
!= Integer comparison (not equal).

Operator Description
exp1 \| exp2 If exp1 is null or 0 return exp2 else return exp1.
If exp1 or exp2 are both not null or not zero return exp1 else return
exp1 \& exp2
0.
Compares exp1 with exp2 which is a regular expression returns the
exp1 : exp2 number of characters matched. The symbols \( \) can be used to
obtain a portion of exp1.

Operator Description
Returns the position in the first string of the first match
index str1 str2
found corresponding to the second string.
length string Returns the length of string.
Returns the substring of str that starts at start and has
substr str start length
length characters long.

Note: using expr you can carry mathematical operations on integer only.

Examples:

$ expr 7 + 5
12
$ i=`expr 3 \* 4 + 2`
$ echo $i
14
$ echo "result = `expr \( $i - 2 \) / 2`"
result = 6

$ a = `expr "abc def " : "abc \(.*\)"`


$ echo $a
def

Special shell variables

These are some variables that have special meanings for the shell

Variable Description
$# Number of arguments.
$* All arguments.
$@ All arguments enclosed in quotes.
$0 Name of the script.
$1 First argument.
$n Replace n by a number between 0 and N to obtain the corresponding
argument.
$! Process id of the last process started in background.
Operator Description
command1 && command2 Causes command2 to be executed only if command1
returns a 0 (zero) exit value.
command1 || command2 Causes command2 to be executed only if command1
returns a nonzero exit value.

Variable Description
$cwd Current working directory.
$shell Pathname of the shell.
$HOME The user login directory.
$? Exit status of the last command 0 (zero) means OK.
$$ Process Id of the current shell.
$- Execution flags.

Exit Status of command

A command is successful if it exits with a status of zero. A nonzero exit code


indicates that an error has occurred.

To check the exit code of the most recent command you executed, use the variable
$?. For example:

grep root /etc/passwd > /dev/null 2>&1


if [ $? -ne 0 ] ; then
echo "No one is in charge!"
fi

Here you execute a grep command and then check the exit status of this command
using the value stored in $?.

Conditional Execution

Two simple forms of conditional execution are available through the commands &&
and || their meanings are the following:

A zero exit value means that the program exited without errors, a nonzero exit value
means that the program exited with an error the return value identifies the error
code.

Examples:

$ test -x myprog.exe && prog.exe


$ cat output.log > /dev/null 2>&1 || cat > output.log

Control structures

In order to control the flow of execution the shell supports the following flow control
structures.
if - The format of the if flow control structure is as follows:

I)

if test-command ; then
command
fi

II)

if test-command ; then
commands
elif test-command ; then
commands
.
.
else
commands
fi

III)

if test-command
then
commands
else
commands
fi

IV)

if test-command
then
commands
fi

The test-command argument is usually a test expression; the command


test supports the following expressions:

File status Test for:


-d filename Directory file.
-L filename Symbolic link.
-e filename File exists.
-f filename Plain ordinary file.
-o filename User owns the file.
-r filename Read access.
-w
Write access.
filename
-x filename Execute access.
-s filename Size greather than 0.
-p filename Named FIFO.
-b filename Block special.
-c filename Character special.

Logical and Relational operators Description


-gt Integers (Greather than).
-lt Integers (Less than).
-ge Integers (Greather or equal to).
-le Integers (Less than or equal to).
-ne Integers (not equal to).
-eq Integers (equal to).
\( \) Expression grouping
-a Logical AND.
-o Logical OR.
! Logical negation.
!= Compare two strings (not equal to).
= Compare two strings (equal to).
-z string String length is zero.
-n string String length is not zero..
string String is not null.

Examples:

#
if test "$1" = "XX" ; then
echo "The first argument is XX"
fi

#
if [ ! -e $HOME/prog.f ] ; then
echo "File does NOT exist"
elif [ -d $HOME/prog.f ] ; then
echo "File is a directory"
elif [ -f $HOME/prog.f ] ; then
echo "File is a plain normal file"
fi

trap - The format of the trap statement is as follows:

trap [command] [n] ...

Runs the command specified by command when the shell receives n


signal(s). The trap commands are executed in order of signal number.
Any attempt to set a trap on a signal that was ignored on entry to the
current shell is ineffective. If you do not specify a command, then all
traps n are reset to their current values. If command is a null string,
this signal is ignored by the shell and by the commands it invokes. If n
is 0 (zero), the command is executed on exit from the shell. If neither
a command nor a signal (n) is specified, trap displays a list of
commands associated with each signal number.

Example:

#
trap abort 1 2 3 4
while true ; do
echo "Program running..."
done

until - The format of the until statement is as follows:

until test-command
do
commands
done

The statement while performs a loop executing the commands block


while test-command is true.

Example:

#
count=0
max=10
until [ $count -gt $max ] ; do
count=`expr $count + 1`
echo "Program running..."
done

while - The format of the while statement is as follows:

while test-command
do
commands
done

The statement while performs a loop executing the commands block


while test-command is true.

Example:

#
count=0
max=10
while [ $count -le $max ] ; do
count=`expr $count + 1`
echo "Program running..."
done

for - The format of the for statement is as follows:

for iterator in items ...


do
commands
done

The statement for performs a loop executing the commands block for
each one of the specified items. In each loop the iterator variable
assumes the value of one item following the specified order. The for
statement can be interrupted with a break or continue statements.
Break terminates the loop and resumes execution on the statement
after the end statement. Continue transfers control to the end
statement which will continue the loop.

Example:

#
for file in *.a
do
echo $file
nm $file | grep gamma
done

case - The format of the case statement is as follows:

case string in
pattern1)
commands
;;
pattern2)
commands
;;
.
.
*)
commands
;;
esac

The case statement implements a multiple branch decision


mechanism. The chosen branch is selected based on the comparison
between the string expression and each pattern.

Example:
#
echo "Answer YES or NO: "
read answer
case "$answer" in
YES)
echo "Answer is YES"
;;
NO)
echo "Answer is NO"
;;
*)
echo "Answer is neither YES or NO"
;;
esac

Functions

A shell function is similar to a shell script since they both store commands, however
a shell function is stored in memory once is loaded from a script. Functions can be
remove from memory with the unset command. The general syntax for a function
is:

function-name ( )
{
commands
.
.
}

Like shell scripts functions accept arguments in the same manner.

Example:
#
findarchive()
{
for file in $1/*.a ; do
nm $file | egrep "^$1|$2"
done
}

findarchive /usr/lib sqrt

The function findarchive accepts two arguments, the name of a directory where
archive files (.a) are kept and the name of a routine to search for in all archive files.
The for loop is used to loop through all the archives in the directory. The nm
command lists all the archived symbols (routines, functions etc.). The command
egrep displays all the lines containing the symbol we are searching for and also lines
beginning with the directory name (the complete pathname of each archive).

Include functions and variable definitions from one file into another file
To include functions and variable definitions defined in one file into another file you
need to use the . command as follows:

. filexit

Here file is the name of the file you want to include

I/O Redirection

Redirection of I/O refers to the multiple ways the Bourne shell can be instructed to
alter where a command gets its input and where it sends its output to. By default the
shell associates the input and output of a command to the login terminal. Users can
change this default behaviour instructing the shell to redirect the input or output to
other device, a file or a command.

Standard I/O file descriptors

Each UNIX process is created with three files already open, they are:

Descriptor Descriptor
Name Meaning
Name Number
Standard Input (stdin) 0 The process input.
Standard
(stdout) 1 The process output.
Output
Where to write error
Standard Error (stderr) 2
messages.

Usually all these descriptor point to the user login terminal.

Redirecting I/O to files

Redirecting Standard Output

To redirect the standard output to a file use the symbol > after the command and its
arguments. The general syntax is:

command > filename

Example:

aflip01> ls -lagF *.f > myfiles.lis


aflip01> cat func1.f func2.f func3.f > functions.f

Redirecting output to an existing file completely overwrites the existing contents.


To redirect and append the command output to an existing file use the notation >>
. The general syntax is:

command >> filename


Example:

aflip01> date >> diskusage.lis ; df >> diskusage.lis


aflip01> cat func1.f func2.f func3.f >> functions.f

Redirecting Standard Error

To redirect the standard error to a file so that error messages use the notation 2> .
The general syntax is:

command 2> filename

Example:

aflip01> cc -oprog1 prog1.c 2> prog1.err


aflip01> du -s 2> dirusage.lis

The above syntax means redirect descritor number 2 (standard error) to a file, in
fact in the place of the number two you can use numbers between 1 and 9 to
redirect any of the first file descriptors, remember 0 is the standard input you can
not redirect descriptor 0 for output unless you close it first with the command <&- .
Standard output can also be closed with the command >&- .
To redirect the standard output and standard error to the same file so that error
messages and output can be found together use the following notation.

command > filename 2>&1

Example:

aflip01> cc -oprog1 prog1.c > prog1.err 2>&1


aflip01> du -s > dirusage.lis 2>&1

The above sintax means to redirect standard output to a file and associate the
descriptor number 2 (standard error) to descriptor number 1 (standard output).
To redirect and append the standard output and standard error to the same file so
that error messages and output can be found together use the following notation.

command >> filename 2>&1

Example:

aflip01> cc -oprog1 prog1.c >> prog1.err 2>&1


aflip01> du -s >> dirusage.lis 2>&1

Redirecting Standard Input

To redirect the standard input to a file in order to force a command to read its input
from a file use the notation < . The general syntax is:

command < filename


Example:

aflip01> stty -a < /dev/tty01


aflip01> ssh afdel02 "setenv DISPLAY xncd39:0.0; ghostview -" <
doc.ps

To use the current standard input file as input until a string marker is found on a line
use the notation << . The general syntax is:

command <<marker

Example:

aflip01> cat <<END


? This is a test `date`
? END
This is a test Wed Nov 11 21:53:23 WET 1998
aflip01>

Note that between the redirection indicator (<<) and the marker string there are no
white spaces.

Redirecting the shell input, output and error descriptors

The shell stdin, stdout and stderr can be redirected to any file through the exec
command.

Redirecting the shell input descriptor

To redirect the shell stdin use the syntax:

exec < filename

Example:

aflip01> exec < infile

Redirecting the shell output descriptor

To redirect the shell stdin use the syntax:

exec > filename

Example:

aflip01> exec > outfile.txt

Redirecting the shell error descriptor

To redirect the shell stdin use the syntax:


exec 2> filename

Example:

aflip01> exec 2> errors.txt

Restoring the input, output and error descriptors

To restore the shell descriptors back to your terminal use the syntax:

exec > `tty` 2>&1 < `tty`

Example:

aflip01> exec > `tty` 2>&1 < `tty`

Redirecting I/O to other commands

The output of a command can also be redirected to other command. The shell uses a
pipe to connect the standard output of a command to the standard input of another
command. A pipe has the same final effect as redirecting the output of the first
command to a file and then redirect the standard input of the next command to read
from the same file. The pipe symbol is the vertical bar | . The general syntax is:

Redirecting Standard Output

To redirect the standard output to other command use the symbol | after the
command and its arguments. The general syntax is:

command1 | command2 ...

Example:

aflip01> ls -l | more
aflip01> find /cern/pro/lib -name '*.a' -exec nm {} \; | grep gamma |
more
aflip01> man csh | a2ps | lpr -Plps

Redirecting Standard Error

To redirect the standard output and standard error to other command use the
following syntax:

command1 2>&1 | command2 ...

Example:

aflip01> f77 prog3.f 2>&1 | error

Discarding the output of a command


Sometimes you will need to execute a command, but you don't want the output
displayed to the screen. In these cases you can discard the output by redirecting it to
the file /dev/null

command > /dev/null

Here command is the name of the command you want to execute. The file is a
special file (called the bit bucket) that automatically discards all its input.

Example

ls –l > /dev/null

This will send out put of ls command to /dev/null and on screen you will not get
anything.

To discard both output of a command and its error output, use standard redirection
to redirect STDERR to STDOUT

cat myfile > /dev/null 2>&1

Debugging Scripts

1. Use echo statements.


2. Use the command set -v to get a verbose dump of each line the shell reads.
Use set +v to turn off verbose mode.
3. Use the command set -x to see what each command expands to. Again, set
+x turns this mode off.

Bourne Shell Built-in Commands

Built-in commands are part of (built into) the shell. Built-in commands are executed
internally without a fork by the shell. If a UNIX command has the same name of an
internal command the internal command will be executed instead.

Command Description
: Null command.
. Execute a shell script as part of the current process (without fork).
`pgm` Execute pgm and replace the text between ` ` by the command output.
break Exit from a FOR, UNTIL or WHILE loop.
bg Move a command to background (zsh, bash, ksh).
cd Change working directory.
continue Jump to the next loop iteration valid for WHILE, UNTIL and FOR loops.
echo Display the arguments.
eval Scan and evaluate the command line.
exec Load a new program into the current process, the current shell is lost.
exit Exit from current shell.
export Place a variable in the environment in order to be used by subprocesses.
fg Move a command to foreground (zsh, bash, ksh).
getopts Parse the shell script arguments.
hash Remember the location of a command in the search path.
jobs List current jobs (zsh, bash, ksh).
pwd Print the pathname of the current directory.
read Read a line from the standard input.
readonly Declare a variable to be readonly.
return Exit from a function.
set Changes the shell flags or command line arguments, without arguments
displays the list of variables.
shift Shift left the line arguments.
stop Stop a background job (zsh, bash, ksh).
test Make comparisons.
times Display times for the current shell and its children.
trap Intercept a signal.
type Display how each argument would be interpreted as a command.
shift Increments the index of the argv array hence shifting the command
arguments by one.
ulimit Limit the size of files written by the shell.
umask Displays and changes the mask for default access permissions.
unset Removes a variable declared with the set command.
wait Causes the C shell to wait until all background processes finish.

Вам также может понравиться