2-Introduction To Shell Scripting
2-Introduction To Shell Scripting
Yao-Yuan Chuang
1
Outline
What is shell?
Basic
Syntax
Lists
Functions
Command Execution
Here Documents
Debug
Regular Expression
Find
2
Why Shell?
The commercial UNIX used Korn Shell
For Linux, the Bash is the default
Why Shell?
For routing jobs, such as system administration, without
writing programs
However, the shell script is not efficient, therefore, can be
used for prototyping the ideas
For example,
% ls al | more (better format of listing
directory)
% man bash | col b | lpr (print man page of man)
3
What is Shell?
Shell is the interface between end user
and the Linux system, similar to the
commands in Windows
Bash is installed as in /bin/sh
Check the version
Other
csh programs
% /bin/sh --version
Kernel
bash
X window
4
Pipe and Redirection
Redirection (< or >)
% ls l > lsoutput.txt (save output to lsoutput.txt)
% ps >> lsoutput.txt (append to lsoutput.txt)
% more < killout.txt (use killout.txt as parameter to
more)
% kill -l 1234 > killouterr.txt 2 >&1 (redirect to the
same file)
% kill -l 1234 >/dev/null 2 >&1 (ignore std output)
Pipe (|)
Process are executed concurrently
% ps | sort | more
% ps xo comm | sort | uniq | grep v sh | more
% cat mydata.txt | sort | uniq | > mydata.txt
(generates an empty file !)
5
Shell as a Language
We can write a script containing many shell commands
Interactive Program:
grep files with POSIX string and print it
% for file in *
> do
> if grep l POSIX $file
> then
> more $file
fi
done
Posix
There is a file with POSIX in it
* is wildcard
% more `grep l POSIX *`
% more $(grep l POSIX *)
% more l POSIX * | more
6
Writing a Script
Use text editor to generate the first file
#!/bin/sh
# first
# this file looks for the files containing POSIX
# and print it
for file in *
do
if grep q POSIX $file
then
echo $file
fi
done
exit 0 exit code, 0 means successful
% /bin/sh first
% chmod +x first
%./first (make sure . is include in PATH parameter)7
Syntax
Variables
Conditions
Control
Lists
Functions
Shell Commands
Result
Document
8
Variables
Variables needed to be declared, note it is case-sensitive
(e.g. foo, FOO, Foo)
Add $ for storing values
% salutation=Hello
% echo $salutation
Hello
% salutation=7+5
% echo $salutation
7+5
% salutation=yes dear
% echo $salutation
yes dear
% read salutation
Hola!
% echo $salutation
Hola!
9
Quoting
Edit a vartest.sh file
Output
#!/bin/sh
Hi there
Hi there
myvar=Hi there
$myvar
$myvar
echo $myvar
Enter some text
echo $myvar
Hello world
echo `$myvar`
$myvar now equals Hello world
echo \$myvar
10
Environment Variables
$HOME home directory
$PATH path
$PS1 (normally %)
$PS2 (normally >)
$$ process id of the script
$# number of input parameters
$0 name of the script file
$IFS separation character (white space)
% echo $*
foo bar bam
% unset IFS
% echo $*
foo bar bam
12
Edit file try_var
#!/bin/sh
salutation=Hello
Parameter echo $salutation
echo The program $0 is now running
echo The parameter list was $*
echo The second parameter was $2
echo The first parameter was $1
echo The users home directory is $HOME
echo Please enter a new greeting
read salutation
echo $salutation
echo The script is now complete
exit 0
%./try_var foo bar baz
Hello
The program ./try_var is now running
The second parameter was bar
The first parameter was foo
The parameter list was foo bar baz
The users home directory is /home/ychuang
Please enter a new greeting
Hola
Hola 13
test or [
if test f fred.c If [ -f fred.c ] if [ -f fred.c ];then
then then ...
... ... fi
fi
fi
16
Condition Structure
#!/bin/sh
echo Is it morning? Please answer yes or no
read timeofday
if [ $timeofday = yes ]; then
echo Good morning
elif [ $timeofday = no ]; then
echo Good afternoon
else
echo Sorry, $timeofday not recongnized. Enter yes or no
exit 1
fi
exit 0
bar
fud
43
#!/bin/sh
19
Loop Structure
#!/bin/sh
Syntax
for foo in 1 2 3 4 5 6 7 8 9 10
while condition
do
do
echo here we go again
statement done
done exit 0
Syntax
until condition #!/bin/sh
do foo = 1
statement while [ $foo le 10 ]
done do
echo here we go again
Note: condition is foo = $foo(($foo+1))
Reverse to while done
How to re-write
exit 0
previous sample? 20
Case Statement
Syntax
case variable in\
pattern [ | pattern ] ) statement;;
pattern [ | pattern ] ) statement;;
#!/bin/sh
esac echo Is it morning? Please answer yes or no
read timeofday
case $timeofday in
yes) echo Good Morning;;
y) echo Good Morning;;
no) echo Good Afternoon;;
n) echo Good Afternoon;;
* ) echo Sorry, answer not recongnized;;
esac 21
exit 0
Case Statement
A much cleaner version
#!/bin/sh
echo Is it morning? Please answer yes or no
read timeofday
case $timeofday in
yes | y | Yes | YES ) echo Good Morning;;
n* | N* ) echo Good Afternoon;;
* ) echo Sorry, answer not recongnized;;
esac
exit 0
#!/bin/sh
touch file_one Check if file exist if not then create one
rm f file_two
Remove a file
if [ -f file_one ] && echo Hello && [-f file_two] && echo there
then
echo in if
else
echo in else Output
fi Hello
exit 0 in else
24
List
OR (||)
statement1 || statement2 || statement3
#!/bin/sh
rm f file_one
if [ -f file_one ] || echo Hello || echo there
then
echo in if
else Output
echo in else Hello
fi in else
exit 0
25
Statement Block
Use multiple statements in the same place
get_comfirm && {
grep v $cdcatnum $stracks_file > $temp_file
cat $temp_file > $tracks_file
echo
add_record_tracks
}
26
Function
You can define functions for structured scripts
function_name() {
statements
}
#!/bin/sh
foo() {
echo Function foo is executing
}
Output
echo script starting
script starting
foo
Function foo is executing
echo script ended
Script ended
exit 0
exit 0 28
Function
Use return to pass a result
#!/bin/sh echo Original parameters are $*
yes_or_no() { if yes_or_no $1
echo Is your name $* ? then
while true echo Hi $1, nice name
do else
echo n Enter yes or no: echo Never mind
read x fi
case $x in exit 0
y | yes ) return 0;;
n | no ) return 1;;
* ) echo Answer yes or no Output
esac ./my_name John Chuang
done Original parameters are John Chuang
} Is your name John?
Enter yes or no: yes 29
#!/bin/sh
rm f fred
if [ -f fred ]; then
:
else
echo file fred did not exist
fi
exit 0
31
Command
continue continues next iteration
#!/bin/sh
rm rf fred*
echo > fred1
echo > fred2
mkdir fred3
echo > fred4
for file in fred*
do
if [ -d $file ]; then
echo skipping directory $file
continue
fi
echo file is $file
done
rm rf fred* 32
exit 0
Command
. ./shell_script execute shell_script
classic_set
#!/bin/sh
verion=classic
PATH=/usr/local/old_bin:/usr/bin:/bin:.
PS1=classic>
latest_set
#!/bin/sh
verion=latest
PATH=/usr/local/new_bin:/usr/bin:/bin:.
PS1=latest version> % . ./classic_set
classic> echo $version
classic
Classic> . latest_set
latest 33
latest version>
Command
echo print string
-n do not output the trailing newline
-e enable interpretation of backslash escapes
\0NNN the character whose ACSII code is NNN
\\ backslash
\a alert
\b backspace
\c suppress trailing newline
\f form feed
\n newline
\r carriage return
\t horizontal tab
\v vertical tab Try these
% echo n string to \n output
34
% foo=10 % foo=10
% x=foo % x=foo
% y=$$x % eval y=$$x
% echo $y
% echo $y
35
Command
exit n ending the script
0 means success
1 to 255 means specific error code
126 means not executable file
127 means no such command
128 or >128 signal
#!/bin/sh
if [ -f .profile ]; then
exit 0
fi
exit 1
36
Command
export gives a value to a parameter
export2 37
Command
expr evaluate expressions
exit 0
40
Command
Shift shift parameter once, $2 to $1, $3 to
$2, and so on
#!/bin/sh
while [ $1 != ]; do
echo $1
shift
done
exit 0
41
Command
trap action after receiving signal
trap command signal
signal explain
HUP (1) hung up
INT (2) interrupt (Crtl + C)
QUIT (3) Quit (Crtl + \)
ABRT (6) Abort
ALRM (14) Alarm
TERM (15) Terminate
42
Command
#!/bin/sh
trap rm f /tmp/my_tmp_file_$$ INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo press interrupt (CTRL-C) to interrupt
while [ -f /tmp/my_tmp_file_$$ ]; do
echo File exists
sleep 1
done
echo The file no longer exists
trap INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo press interrupt (CTRL-C) to interrupt
while [ -f /tmp/my_tmp_file_$$ ]; do
echo File exists
sleep 1
done
echo we never get there
exit 0 43
Command
creating file /tmp/my_file_141
press interrupt (CTRL-C) to interrupt
File exists
File exists
File exists
File exists
The file no longer exists
Creating file /tmp/my_file_141
Press interrupt (CTRL-C) to interrupt
File exists
File exists
File exists
File exists
44
Command
Unset remove parameter or function
#!/bin/sh
foo=Hello World
echo $foo
unset $foo
echo $foo
45
Pattern Matching
find search for files in a directory hierarchy
find [path] [options] [tests] [actions]
options
-depth find content in the directory
-follow follow symbolic links
-maxdepths N fond N levels directories
-mount do not find other directories
tests
-atime N accessed N days ago
-mtime N modified N days ago
-new otherfile name of a file
-type X file type X
-user username belong to username
46
Pattern Matching
operator
! -not test reverse
-a -and test and
-o -or test or
action
-exec command execute command
-ok command confirm and exectute command
-print print
-ls ls dils
47
Pattern Matching
Find files newer than while2 then print only files
% find . newer while2 type f print
48
Pattern Matching
grep print lines matching a pattern
(General Regular Expression Parser)
grep [options] PATTERN [FILES]
option
-c print number of output context
-E Interpret PATTERN as an extended regular expression
-h Supress the prefixing of filenames
-i ignore case
-l surpress normal output
-v invert the sense of matching
% grep in words.txt
% grep c in words.txt words2.txt
% grep c v in words.txt words2.txt
49
Regular Expressions
a regular expression (abbreviated as regexp or regex, with
plural forms regexps, regexes, or regexen) is a string that
describes or matches a set of strings, according to certain syntax
rules.
Syntax
^ Matches the start of the line
$ Matches the end of the line
. Matches any single character
[] Matches a single character that is contained within the
brackets
[^] Matches a single character that is not contained within the
brackets
() Defines a "marked subexpression
{x,y}Match the last "block" at least x and not more than y
times
50
Regular Expressions
Examples:
".at" matches any three-character string like
hat, cat or bat
"[hc]at" matches hat and cat
"[^b]at" matches all the matched strings from
the regex ".at" except bat
"^[hc]at" matches hat and cat but only at the
beginning of a line
"[hc]at$" matches hat and cat but only at the
end of a line
51
Regular Expressions
POSIX class similar to meaning
[:upper:] [A-Z] uppercase letters
[:lower:] [a-z] lowercase letters
[:alpha:] [A-Za-z] upper- and lowercase letters
[:alnum:] [A-Za-z0-9] digits, upper- and lowercase
letters
[:digit:] [0-9] digits
[:xdigit:] [0-9A-Fa-f] hexadecimal digits
[:punct:] [.,!?:...] punctuation
[:blank:] [ \t] space and TAB characters only
[:space:] [ \t\n\r\f\v]blank (whitespace) characters
[:cntrl:] control characters
[:graph:] [^ \t\n\r\f\v] printed characters
[:print:] [^\t\n\r\f\v] printed characters and space
53
Regular Expressions
Search for lines ending with e
% grep e$ words2.txt
Search for a
% grep a[[:blank:]] word2.txt
54
Command
$(command) to execute command in a script
Old format used ` but it can be confused with
#!/bin/sh
echo The current directory is $PWD
echo the current users are $(who)
55
Arithmetic Expansion
Use $(()) instead of expr to evaluate arithmetic equation
#!/bin/sh
x=0
while [ $x ne 10]; do
echo $x
x=$(($x+1))
done
exit 0
56
Parameter Expansion
Parameter Assignment
foo=fred ${param:-default} set default if null
echo $foo ${#param} length of param
${param%word} remove smallest suffix pattern
#!/bin/sh ${param%%word} remove largest suffix pattern
for i in 1 2 ${param#word} remove smallest prefix pattern
do ${param##word} remove largest prefix pattern
my_secret_process $i_tmp
done
Gives result
mu_secret_process:
too few arguments
#!/bin/sh
for i in 1 2
do
my_secret_process ${i}_tmp 57
done
Parameter Expansion
#!/bin/sh
unset foo
echo ${foo:-bar}
Output
foo=fud bar
echo ${foo:-bar} fud
usr/bin/X11/startx
foo=/usr/bin/X11/startx startx
echo ${foo#*/} /usr/local/etc
echo ${foo##*/} /usr
bar=/usr/local/etc/local/networks
echo ${bar%local*}
echo ${bar%%local*}
Exit 0
58
Here Documents
A here document is a special-purpose code block, starts
with <<
#!/bin.sh
#!/bin.sh ed a_text_file <<HERE
cat <<!FUNKY! 3
d
hello
.,\$s/is/was/
this is a here w
document q a_text_file
HERE That is line 1
!FUNCKY!
exit 0 That is line 2
exit 0 That is line 3
That is line 4
Output
That is line 1
That is line 2
That was line 4 59
Debug
sh n<script> set -o noexec check syntax
set n
set o xtrace
set +o xtrace
trap echo Exiting: critical variable =$critical_variable
EXIT
60
References
Bash Beginners Guide (http://tldp.org/LDP/Bash-
Beginners-Guide/)
(http://linux.tnc.edu.tw/techdoc/)
61