shell编程一本全.docx
《shell编程一本全.docx》由会员分享,可在线阅读,更多相关《shell编程一本全.docx(19页珍藏版)》请在冰豆网上搜索。
shell编程一本全
现在市场上很多名叫一本全,一本通的辅导书。
以为不过是徒有虚名,shell编程一本全则是真正的shell参考手册,做到了大而全哦。
不信你看看:
BourneShell
介绍:
BourneShell基础及其他很多有用的特性,shell编程及组织。
主要内容:
.shell基础基本介绍,环境,选项,特殊字符
.shell变量用户定义变量,环境变量,位置变量(shell参数)
.shellscript编程
条件测试,循环及重复控制
.shell定制
1.shell基础知识
作者:
StephenBourne在Bell实验室开发
建议:
mansh查看相关UNIX上的改进或特性
(1)shell提示符及其环境
/etc/passwd文件
提示符:
$
/etc/profile$HOME/.profile
(2)shell执行选项
-n测试shellscript语法结构,只读取shellscript但不执行
-x进入跟踪方式,显示所执行的每一条命令,用于调度
-aTagallvariablesforexport
-c"string"从strings中读取命令
-e非交互方式
-f关闭shell文件名产生功能
-hlocateandrememberfunctionsasdefind
-i交互方式
-k从环境变量中读取命令的参数
-r限制方式
-s从标准输入读取命令
-t执行命令后退出(shellexits)
-u在替换中如使用未定义变量为错误
-vverbose,显示shell输入行
这些选项可以联合使用,但有些显然相互冲突,如-e和-i.
(3)受限制shell(RestirctedShell)
sh-r或/bin/rsh
不能执行如下操作:
cd,更改PATH,指定全路径名,输出重定向,因此可以提供一个较
好的控制和安全机制。
通常rsh用于应用型用户及拨号用户,这些用户通常是看不到提
示符的。
通常受限制用户的主目录是不可写的。
不足:
如果用户可以调用sh,则rsh的限制将不在起作用,事实上如果用户在vi及more
程序中调用shell,而这时rsh的限制将不再起作用。
(4)用set改变shell选项
用户可以在$提示符下用set命令来设置或取消shell的选项。
使用-设置选项,+取消相应
选项,大多数UNIX系统允许a,e,f,h,k,n,u,v和x的开关设置/取消。
set-xv
启动跟踪方式;显示所有的命令及替换,同样显示输入。
set-tu
关闭在替换时对未定义变量的检查。
使用echo$-显示所有已设置的shell选项。
(5)用户启动文件.profile
PATH=$PATH:
/usr/loacl/bin;exportPATH
(6)shell环境变量
CDPATH用于cd命令的查找路径
HOME/etc/passwd文件中列出的用户主目录
IFSInternalFieldSeparator,默认为空格,tab及换行符
MAIL/var/mail/$USERNAMEmail等程序使用
PATH
PS1,PS2默认提示符($)及换行提示符(>)
TERM终端类型,常用的有vt100,ansi,vt200,xterm等
示例:
$PS1="test:
";exportPS1
test:
PS1="$";exportPS1
$echo$MAIL
/var/mail/username
(7)保留字符及其含义
$shell变量名的开始,如$var
|管道,将标准输出转到下一个命令的标准输入
#注释开始
&在后台执行一个进程
?
匹配一个字符
*匹配0到多个字符(与DOS不同,可在文件名中间使用,并且含.)
$-使用set及执行时传递给shell的标志位
$!
最后一个子进程的进程号
$#传递给shellscript的参数个数
$*传递给shellscript的参数
$@所有参数,个别的用双引号括起来
$?
上一个命令的返回代码
$0当前shell的名字
$n(n:
1-)位置参数
$$进程标识号(ProcessIdentifierNumber,PID)
>file输出重定向
>fiile输出重定向,append
转义符及单引号:
$echo"$HOME$PATH"
/home/hbwork/opt/kde/bin:
/usr/local/bin:
/bin:
/usr/bin:
/usr/X11R6/bin:
$echo'$HOME$PATH'
$HOME$PATH
$echo$HOME$PATH
$HOME/opt/kde/bin:
/usr/local/bin:
/bin:
/usr/bin:
/usr/X11R6/bin:
/home/hbw
ork/bin
其他:
$dir=ls
$$dir
$aliasdirls
$dir
ls>filelist
ls>>filelist
wc-l/dev/rmt/0h
书写程序的目的是一次编程,多次使用(执行)!
$cat>backup.sh
cd/home/hbwork
ls*|cpio-o>/dev/rmt/0h
^D
执行:
$shbackup.sh
或:
$chmod+xbackup.sh
$./backup.sh
技巧:
在shellscript中加入必要的注释,以便以后阅读及维护。
(2)shell是一个(编程)语言
同传统的编程语言一样,shell提供了很多特性,这些特性可以使你的shellscript
编程更为有用,如:
数据变量、参数传递、判断、流程控制、数据输入和输出,子
程序及以中断处理等。
.在shell编程中使用数据变量可以将程序变量更为通用,如在上面backup.sh中:
cd$WORKDIR
ls*|cpio-o>/dev/rmt/0h
.Shell编程中的注释以#开头
.对shell变量进行数字运算,使用expr命令
exprintegeroperatorinteger
其中operator为+-*/%,但对*的使用要用转义符,如:
$expr4*5
20
$int=`expr5+7`
$echo$int
12
(3)Shell编程的参数传递,可通过命令行参数以及交互式输入变量(read)
restoreall.sh对backup.sh程序的备份磁带进行恢复
$cat>restoreall.sh
cd$WORKDIR
cpio-i/dev/rmt/0h
rm-rf*
改进如下:
#当使用了管道命令时,管理命令的返回代码为最后一个命令的返回代码
ifls-a|cpio-o>/dev/rmt/0h
then
rm-rf*
fi
.if-then-else语句
ifcommand_1
then
command_2
else
command_3
fi
技巧:
由于shell对命令中的多余的空格不作任何处理,一个好的程序员会用这一特
性
对自己的程序采用统一的缩进格式,以增强自己程序的可读性.
.使用test命令进行进行条件测试
格式:
testconditions
test在以下四种情况下使用:
a.字符比较b.两个整数值的比较
c.文件操作,如文件是否存在及文件的状态等
d.逻辑操作,可以进行and/or,与其他条件联合使用
a.测试字符数据:
shell变量通常民政部下均作为字符变量
str1=str2二者相长,相同
str1!
=str2不同
-nstringstring不为空(长度不为零)
-zstringstring为空
stringstring不为空
例:
$str1=abcd#在含有空格时必须用引号括起来
$test$str1=abcd
$echo$?
0
$str1="abcd"
$test$str1=abcd
$echo$?
1
Note:
在test处理含有空格的变量时最好用引号将变量括起来,否则会出现错误的
结果,
因为shell在处理命令行时将会去掉多余的空格,而用引号括起来则可以防止
shell去掉这些空格.
例:
$str1=""
$test$str1
$echo$?
1
$test"$str1"
$echo$?
0
$test-n$str1
test:
argumentexpected
$test-n"$str1"
$echo$?
0
$
b.整数测试:
test与expr相同,可以将字符型变量转换为整数进行操作,expr进行
整数的算术运算,而test则进行逻辑运算.
表达式说明
---------------------------------------
int1-eqint2相等?
int1-neint2不等?
int1-gtint2int1>int2?
int1-geint2int1>=int2?
int1-ltint2int1empty
$test-rempty
$echo$?
0
$test-sempty
1
$test!
-sempty
$echo$?
0
e.测试条件之逻辑运算
-aAnd
-oOr
例:
$test-rempty-a-sempty
$echo$?
1
f.进行test测试的标准方法
因为test命令在shell编程中占有很重要的地位,为了使shell能同其他编程语言
一样
便于阅读和组织,BourneShell在使用test测试时使用了另一种方法:
用方括号将
整个
test测试括起来:
$int1=4
$[$int1-gt2]
$echo$?
0
例:
重写unload程序,使用test测试
#!
/bin/sh
#unload-programtobackupandremovefiles
#syntax:
unloaddirectory
#checkarguments
if[$#-ne1]
then
echo"usage:
$0directory"
exit1
fi
#checkforvaliddirectoryname
if[!
-d"$1"]
then
echo"$1isnotadirectory"
exit2
fi
cd$1
ls-a|cpio-o>/dev/rmt/0h
if[$?
-eq0]
then
rm-rf*
else
echo"Aproblemhasoccuredincreatingbackup"
echo"Thedirectorywillnotbeereased"
echo"Pleasecheckthebackupdevice"
exit3
fi
#endofunload
在如上示例中出现了exit,exit有两个作用:
一是停止程序中其他命令的执行,二
是
设置程序的退出状态
g.if嵌套及elif结构
ifcommand
then
command
else
ifcommand
then
command
else
ifcommand
then
command
fi
fi
fi
改进:
使用elif结构
ifcommand
then
command
elifcommand
then
command
elifcommand
then
command
fi
elif结构同if结构类似,但结构更清淅,其执行结果完全相同.
--
BourneShell及Shell编程
(2)
h.交互式从键盘读入数据
使用read语句,其格式如下:
readvar1var2...varn
read将不作变量替换,但会删除多余的空格,直到遇到第一个换行符(回车),
并将输入值依次赋值给相应的变量。
例:
$readvar1var2var3
Hellomyfriends
$echo$var1$var2$var3
Hellomyfriends
$echo$var1
Hello
$readvar1var2var3
Hellomydearfriends
$echo$var3
dearfriendswhile循环:
格式:
whilecommand
do
command
command
command
...
done
例:
计算1到5的平方
#!
/bin/sh
#
#Filename:
square.sh
int=1
while[$int-le5]
do
sq=`expr$int*$int`
echo$sq
int=`expr$int+1`
done
echo"Jobcompleted"
$shsquare.sh
1
4
9
16
25
Jobcompleted
until循环结构:
格式:
untilcommand
do
command
command
....
command
done
示例:
使用until结构计算1-5的平方
#!
/bin/sh
int=1
until[$int-gt5]
do
sq=`expr$int*$int`
echo$sq
int=`expr$int+1`
done
echo"Jobcompleted"
使用shift对不定长的参数进行处理
在以上的示例中我们总是假设命令行参数唯一或其个数固定,或者使用$*将整个命
令
行参数传递给shellscript进行处理。
对于参数个数不固定并且希望对每个命令参
数
进行单独处理时则需要shift命令。
使用shift可以将命令行位置参数依次移动位置
,
即$2->$1,$3->$2.在移位之前的第一个位置参数$1在移位后将不在存在。
示例如下:
#!
/bin/sh
#
#Filename:
shifter
until[$#-eq0]
do
echo"Argumentis$1and`expr$#-1`argument(s)remain"
shift
done
$shifter1234
Argumentis1and3argument(s)remain
Argumentis2and2argument(s)remain
Argumentis3and1argument(s)remain
Argumentis4and0argument(s)remain
$
使用shift时,每进行一次移位,$#减1,使用这一特性可以用until循环对每个参
数进行处理,如下示例中是一个求整数和的shellscript:
#!
/bin/sh
#sumints-aprogramtosumaseriesofintegers
#
if[$#-eq0]
then
echo"Usage:
sumintsintegerlist"
exit1
fi
sum=0
until[$#-eq0]
do
sum=`expr$sum+$1`
shift
done
echo$sum
$shsumints32434341234
438
$
使用shift的另一个原因是BourneShell的位置参数变量为$1~$9,因此通过位置变
量
只能访问前9个参数。
但这并不等于在命令行上最多只能输入9个参数。
此时如果想
访问
前9个参数之后的参数,就必须使用shift.
另外shift后可加整数进行一次多个移位,如:
shift3
.for循环
格式:
forvarinarg1arg2...argn
do
command
....
command
done
示例:
$forletterinabcde;doecho$letter;done
a
b
c
d
e
对当前目录下的所有文件操作:
$foriin*
do
if[-f$i]
then
echo"$iisafile"
elif[-d$i]
echo"$iisadirectory"
fi
done
求命令行上所有整数之和:
#!
/bin/sh
sum=0
forINTin$*
do
sum=`expr$sum+$INT`
done
echo$sum
从循环中退出:
break和continue命令
break立即退出循环
continue忽略本循环中的其他命令,继续下一下循环
在shell编程中有时我们要用到进行无限循环的技巧,也就是说这种循环一直执行
碰
到break或continue命令。
这种无限循环通常是使用true或false命令开始的。
UNIX
系统中的true总是返加0值,而false则返回非零值。
如下所示:
#一直执行到程序执行了break或用户强行中断时才结束循环
whiletrue
do
command
....
command
done
上面所示的循环也可以使用untilfalse,如下:
untilfalse
do
command
....
command
done
在如下shellscript中同时使用了continue,break以及case语句中的正规表达式用
法:
#!
/bin/sh
#Interactiveprogramtorestore,backup,orunload
#adirectory
echo"WelcometothemenudrivenArchiveprogram"
whiletrue
do
#DisplayaMenu
echo
echo"MakeaChoicefromtheMenubelow"
echo_
echo"1RestoreArchive"
echo"2Backupdirectory"
echo"3Unloaddirectory"
echo"4Quit"
echo
#Readtheuser'sselection
echo-n"EnterChoice:
"
readCHOICE
case$CHOICEin
[1-3])echo
#Readandvalidatethenameofthedirectory
echo-n"Whatdirectorydoyouwant?
"
readWORKDIR
if[!
-d"$WORKDIR"]
then
echo"Sorry,$WORKDIRisnotadirectory"
continue
fi
#Makethedirectorythecurrentworkingdirectory
cd$WORKDIR;;
4):
;;#:
为空语句,不执行任何动作
*)echo"Sorry,$CHOICEisnotavalidchoice"
continue
esac
case"$CHOICE"in
1)echo"Restoring..."
cpio-i/dev/rmt/0h;;
3)echo"Unloading..."
ls|cpio-o>/dev/rmt/0h;;
4)echo"Quitting"
break;;
esac
#Checkforcpioerrors
if[$?
-ne0]
then
echo"Aproblemhasoccurredduringtheprocess"
if[$CHOICE=3]
then
echo"Thedirectorywillnotbeerased"
fi
echo"Pleasecheckthedeviceandtryagain"
continue
else
if[$CHOICE=3]
then
rm*
fi
fi
done
(6)结构化编程:
定义函数
同其他高级语言一样,shell也提供了函数功能。
函数通常也称之为子过程(subroutine)
其定义格式如下:
funcname()
{
command
...
command;#分号
}
定义函数之后,可以在shell中对此函数进行调用,使用函数定义可以将一个复杂的程序
分
为多个可管理的程序段,如下所示:
#startprogram
setup()
{command