鸟哥学习 Shell Scripts.docx
《鸟哥学习 Shell Scripts.docx》由会员分享,可在线阅读,更多相关《鸟哥学习 Shell Scripts.docx(46页珍藏版)》请在冰豆网上搜索。
鸟哥学习ShellScripts
引用:
学习ShellScripts
如果您真的很想要走信息这条路,并且想要好好的管理好属于您的主机,那么,别说鸟哥不告诉您,ShellScripts真的是必须要学习的一项课题呢!
基本上,shellscript有点像是早期的批次档,亦即是将一些指令汇整起来一次执行,但是Shellscript拥有更强大的功能,那就是,他可以进行类似程序(program)的撰写,并且,不需要经过编译(compiler)就能够执行,真的很方便。
加上,我们可透过shellscript来简化我们日常的工作管理,而且,整个Linux环境中,一些服务(services)的启动都是透过shellscript的,如果您对于script不了解,嘿嘿!
发生问题时,可真是会求助无门喔!
所以,好好的学一学他吧!
1.什么是ShellScript
1.1干嘛学习shellscripts?
1.2第一支script的撰写与执行
1.3撰写shellscript的良好习惯建立
2.简单的shellscript练习:
3.善用判断式:
3.1利用test指令的测试功能
3.2利用判断符号[]
3.3Shellscript的预设变数($0,$1...)
4.条件判断式:
4.1利用if....then
4.2利用case.....esac判断
4.3利用function功能
5.循环(loop)
5.1while....do....done,until....do....done
5.2for...do...done
6.shellscript的追踪与debug
7.本章习题练习
--------------------------------------------------------------------------------
什么是Shellscripts?
这个有趣的问题赶紧来回答看看,什么是shellscript呢?
shell我们在认识bash当中已经提过了,那是一个文字接口底下让我们与系统沟通的一个工具接口,那么script是啥?
字面上的意义,script是『脚本、剧本』的意思。
整句话是说,shellscript是针对shell所写的『剧本!
』什么东西啊?
呵呵!
其实,shellscript是利用shell的功能所写的一个『程序(program)』,这个程序是使用纯文字文件,将一些shell的语法与指令写在里面,搭配正规表示法、管线命令与数据流重导向等功能,以达到我们所想要的处理目的。
所以,简单的说,shellscript就像是早期DOS年代的批次檔(.bat),最简单的功能就是将许多指令汇整写在一起,让使用者很轻易的就能够onetouch(执行一个档案"shellscript",就能够一次执行多个指令),而,shellscript更提供数组、循环、条件与逻辑判断等重要功能,让使用者也可以直接以shell来撰写程序,而不必使用类似C程序语言等传统程序撰写的语法呢!
那,这么说您可以了解了吗?
是的!
shellscript可以简单的被看成是批次档,也可以被说成是一个程序语言,且这个程序语言由于都是利用shell与相关工具指令,所以不需要编译即可执行,且拥有不错的除错(debug)工具,所以,他可以帮助系统管理员快速的管理好主机。
--------------------------------------------------------------------------------
干嘛学习shellscripts?
这是个好问题,我又干嘛一定要学shellscript?
我又不是信息人,没有写程序的概念,那我干嘛还要学shellscript呢?
不要学可不可以啊?
呵呵~如果Linux对您而言,您只是想要『会用』而已,那么,不需要学shellscript也还无所谓,这部分先给他跳过去,等到有空的时候,再来好好的瞧一瞧。
但是,如果您是真的想要玩清楚Linux的来龙去脉,那么shellscript就不可不知,为什么呢?
因为:
自动化管理的重要依据:
不用鸟哥说您也知道,管理一部主机真不是件简单的事情,每天要进行的任务就有:
查询登录档、追踪流量、监控使用者使用主机状态、主机各项硬设备状态、主机软件更新查询、更不要说得应付其它使用者的突然要求了。
而这些工作,您想要自行手动处理,还是写个简单的程序来帮您每日自动处理分析,若有问题才通知您呢?
当然是让系统自动工作比较好,对吧!
呵呵~这就得要良好的shellscript来帮忙的啦!
追踪与管理系统的重要工作:
虽然我们还没有提到服务启动的方法,不过,这里可以先提一下,我们Linux系统的服务(services)启动的接口,在/etc/init.d/这个目录下,所有的档案都是scripts;另外,包括开机(booting)过程也都是利用shellscript来帮忙搜寻系统的相关设定数据,然后再代入各个服务的设定参数啊!
举例来说,如果我们想要重新启动系统登录文件,可以使用:
『/etc/init.d/syslogdrestart』,那个syslogd档案就是script啦!
另外,我曾经在某一代的FC上面发现,启动MySQL这个数据库服务时,确实是可以启动的,但是屏幕上却老是出现『failure』,后来才发现,原来是启动MySQL那个script会主动的以『空的密码』去尝试登入MySQL,但我修改过MySQL的密码啰~当然就登入失败~后来改了改script,就略去这个问题啦!
如此说来,script确实是需要学习的啊!
简单入侵侦测功能:
当我们的系统有异状时,大多会将这些异状记录在系统记录器,也就是我们常提到的『系统登录文件』,那么我们可以在固定的几分钟内主动的去分析系统登录文件,若察觉有问题,就立刻通报管理员,或者是立刻加强防火墙的设定规则,如此一来,您的主机可就能够达到『自我保护』的聪明学习功能啦~举例来说,我们可以通过shellscript去分析『当该封包尝试几次还是联机失败之后,就予以抵挡住该IP』之类的举动,例如鸟哥写过一个关于抵挡砍站软件的shellscript,就是用这个想法去达成的呢!
连续指令单一化:
其实,对于新手而言,script最简单的功能就是:
『汇整一些在commandline下达的连续指令,将他写入scripts当中,而由直接执行scripts来启动一连串的commandline指令输出入!
』例如:
防火墙连续规则(iptables),开机加载程序的项目(就是在/etc/rc.d/rc.local里头的数据),等等都是相似的功能啦!
其实,说穿了,如果不考虑program的部分,那么scripts也可以想成,仅是帮我们把一大串的指令汇整在一个档案里面,而直接执行该档案就可以执行那一串又臭又长的指令段!
就是这么简单啦!
简易的数据处理:
由前一章正规表示法的awk程序说明中,您可以发现,awk可以用来处理简单的数据数据呢!
例如薪资单的处理啊等等的。
shellscript的功能更强大,例如鸟哥曾经用shellscript直接处理数据数据的比对啊,文字数据的处理啊等等的,撰写方便,速度又快(因为在Linux效能较佳),真的是很不错用的啦!
跨平台支持与学习历程较短:
几乎所有的UnixLike上面都可以跑shellscript,连MSWindows系列也有相关的仿真器可以用,此外,shellscript的语法是相当亲和的,看都看的懂得文字,而不是机器码,很容易学习~这些都是您可以加以考虑的学习点啊!
上面这些都是您考虑学习shellscript的特点~此外,shellscript还可以简单的以vi来直接编写,实在是很方便的好东西!
所以,还是建议您学习一下啦。
不过,虽然shellscript号称是程序(program),但实际上,shellscript处理数据的速度上是不太够的。
因为shellscript用的是外部的指令与bashshell的一些预设工具,所以,他常常会去呼叫外部的函式库,因此,运算速度上面当然比不上传统的程序语言。
所以啰,shellscript用在系统管理上面是很好的一项工具,但是用在处理大量数值运算上,就不够好了~而且还很麻烦,因为:
Shellscripts的速度较慢,且使用的CPU资源较多,造成主机资源的分配不良。
还好,我们确实很少看到利用shellscript在进行大量数据运算的,所以,不必担心的啦!
--------------------------------------------------------------------------------
第一支script的撰写与执行
如同前面讲到的,shellscript其实就是纯文字文件(ASCII),我们可以编辑这个档案,然后让这个档案来帮我们一次执行多个指令,或者是利用一些运算与逻辑判断来帮我们达成某些功能。
所以啦,要编辑这个档案的内容时,当然就需要具备有bashshell指令下达的相关认识。
我们说过,要下达指令需要注意的事项在bash章节内已经提过,在shellscript的撰写同样需要用到这些注意事项的:
如同前面bashcommand提到的,指令与参数间的多个空白会被忽略掉;
而空白行也将被忽略掉!
,并且[tab]也是不会被理会的!
如果读取到一个Enter符号(CR)),就尝试开始执行该行命令;
至于如果一行的内容太多,则可以使用\[Enter]来延伸至下一行;
此外,使用最多的#可做为批注!
任何加在#后面的字,将全部被视为批注文字而被忽略!
如此一来,我们在script内所撰写的程序,就会被一行一行的执行。
好了,那么这个程序假设文件名是shell.sh好了,如何执行这个档案?
很简单,可以有底下几个方法:
将shell.sh加上可读与执行(rx)的权限,然后就能够以./shell.sh来执行了;
直接以shshell.sh的方式来直接执行即可。
反正重点就是要让那个shell.sh内的指令可以被执行的意思啦!
咦!
那我为何需要使用./shell.sh来下达指令?
还记得我们在bash里面一直强调的,指令是否能够被执行与PATH这个环境变量有关,所以,要执行『目前这个目录下的某个档案』就需要加上./这个目录啦!
另外,其实您也可以将shell.sh放在您家目录下的~/bin这个目录中,然后利用PATH="$PATH":
~/bin的设定,嘿嘿,就能够直接执行您的script啰~^_^
那,为何shshell.sh也可以执行呢?
这是因为/bin/sh其实就是/bin/bash,使用shshell.sh亦即告诉系统,我想要直接以bash的功能来执行shell.sh这个档案内的相关指令的意思。
而我们也可以利用sh的参数,如-n及-x来检查与追踪shell.sh的语法是否正确呢!
^_^
--------------------------------------------------------------------------------
撰写第一支script
不论是那个门派,要学武功要从扫地做起,那么要学程序呢?
呵呵,肯定是由『秀出HelloWorld!
』这个字眼开始的!
OK!
那么鸟哥就先写一支script给大家瞧一瞧:
[root@linux~]#mkdirscripts;cdscripts
[root@linuxscripts]#vish01.sh
#!
/bin/bash
#Program:
#Thisprogramisusedtoshow"HelloWorld!
"inscreen.
#History:
#2005/08/23VBirdFirstrelease
PATH=/bin:
/sbin:
/usr/bin:
/usr/sbin:
/usr/local/bin:
/usr/local/sbin:
~/bin
exportPATH
echo-e"HelloWorld!
\a\n"
exit0
在我们这个章节当中,请将所有的撰写的script放置到您家目录的~/scripts这个目录内,比较好管理啦!
上面的写法当中,我主要将整个程序的撰写分成数段,大致是这样:
第一行#!
/bin/bash在宣告这个script使用的shell名称:
因为我们使用的是bash,所以,必须要以『#!
/bin/bash』来宣告这个档案内的语法使用bash的语法!
那么当这个程序被执行时,他就能够加载bash的相关环境设定档,并且执行bash来使我们底下的指令能够执行!
这很重要的!
(在很多状况中,如果没有设定好这一行,那么该程序很可能会无法执行,因为系统可能无法判断该程序需要使用什么shell来执行啊!
)
程序内容的宣告:
整个script当中,除了第一行的#!
是用来宣告shell的之外,其它的#都是『批注』用途!
所以上面的程序当中,第二行以下就是用来说明整个程序的状态。
一般来说,建议您一定要养成说明该script的:
1.内容与功能;2.版本信息;3.作者与联络方式;4.建檔日期;5.历史纪录等等。
这将有助于未来程序的改写与debug呢!
主要环境变量的宣告:
建议务必要将一些重要的环境变量设定好,鸟哥个人认为,PATH是当中最重要的!
如此一来,则可让我们这支程序在进行时,可以直接下达指令,而不必写绝对路径呢!
比较好啦!
主要程序部分
就将主要的程序写好即可!
在这个例子当中,就是echo那一行啦!
执行成果告知
是否记得我们在bash里面要讨论一个指令的执行成功与否,可以使用$?
这个变量来观察~那么我们也可以利用exit这个指令来让程序中断,并且回传一个数值给系统。
在我们这个例子当中,我使用exit0,这代表离开script,并且回传一个0给系统,所以我执行完这个script后,若接着下达echo$?
则可得到0的值喔!
更聪明的读者应该也知道了,呵呵!
利用这个exitn的功能,我们还可以自订错误讯息,让这支程序变得更加的smart呢!
接下来执行看看结果是怎样吧?
[root@linuxscripts]#shsh01.sh
HelloWorld!
您会看到屏幕是这样,而且应该还会听到『咚』的一声,为什么呢?
还记得前一章提到的printf吧?
用echo接着那些特殊的按键也可以发生同样的事情~不过,echo必须要加上-e的参数才行!
呵呵!
在您写完这个小script之后,您就可以大声的说:
『我也会写程序了』!
哈哈!
很简单有趣吧~^_^
另外,你也可以利用:
『chmoda+xsh01.sh;./sh01.sh』来执行这个script的呢!
--------------------------------------------------------------------------------
撰写shellscript的良好习惯建立
一个良好习惯的养成是很重要的~大家在刚开始撰写程序的时候,最容易忽略这部分,认为程序写出来就好了,其它的不重要。
其实,如果程序的说明能够更清楚,那么对您自己是有很大的帮助的。
举例来说,鸟哥自己为了自己的需求,曾经撰写了不少的script来帮我进行主机IP的侦测啊、登录档分析与管理啊、自动上传下载重要设定档啊等等的,不过,早期就是因为太懒了,管理的主机又太多了,常常同一个程序在不同的主机上面进行更改,到最后,到底哪一支才是最新的都记不起来,而且,重点是,我到底是改了哪里?
?
为什么做那样的修改?
都忘的一乾二净~真要命~
所以,后来鸟哥在写程序的时候,通常会比较仔细的将程序的设计过程给他记录下来,而且还会记录一些历史纪录,如此一来,好多了~至少很容易知道我修改了哪些数据,以及程序修改的理念与逻辑概念等等,在维护上面是轻松很多很多的喔!
另外,在一些环境的设定上面,毕竟每个人的环境都不相同,为了取得较佳的执行环境,我都会自行先定义好一些一定会被用到的环境变量,例如PATH这个玩意儿!
这样比较好啦~所以说,建议您一定要养成良好的script撰写习惯,在每个script的文件头处记录好:
script的功能;
script的版本信息;
script的作者与联络方式;
script的版权宣告方式;
script的History(历史纪录);
script内较特殊的指令,使用绝对路径的方式来下达;
script运作时需要的环境变量预先宣告与设定。
--------------------------------------------------------------------------------
简单的shellscript练习
在第一支shellscript撰写完毕之后,相信您应该具有基本的撰写功力了。
接下来,在开始更深入的程序概念之前,我们先来玩一些比较有趣的简单的小范例好了。
底下的范例中,达成结果的方式相当的多,建议您先自行撰写看看,写完之后再与鸟哥写的内容比对,这样才能更加深概念喔!
好!
不啰唆,我们就一个一个来玩吧!
--------------------------------------------------------------------------------
变量内容由使用者决定
很多时候我们需要使用者输入一些内容,好让程序可以顺利运作。
简单的来说,大家应该都有安装过软件的经验,安装的时候,他不是会问您『要安装到那个目录去?
』吗?
那个让使用者输入的数据的动作,就是让使用者输入变量内容啦。
你应该还记得在bash的时候,我们有学到一个read指令吧?
忘记的话,请自行回头去阅读一番。
现在,请你以read指令的用途,撰写一个script,他可以让使用者输入:
1firstname与2.lastname,最后并且在屏幕上显示:
『Yourfullnameis:
』的内容:
[root@linuxscripts]#vish02.sh
#!
/bin/bash
#Program:
#Letuserkeyintheirfirstandlastname,andshowtheirfullname.
#History:
#2005/08/23VBirdFirstrelease
PATH=/bin:
/sbin:
/usr/bin:
/usr/sbin:
/usr/local/bin:
/usr/local/sbin:
~/bin
exportPATH
read-p"Pleaseinputyourfirstname:
"firstname
read-p"Pleaseinputyourlastname:
"lastname
echo-e"\nYourfullnameis:
$firstname$lastname"
将上面这个sh02.sh执行一下,你就能够发现使用者自己输入的变量可以被取用的哩!
很不错吧!
加油!
--------------------------------------------------------------------------------
利用date进行档案的建立
想象一个状况,如果我每天要进行备份,而备份的数据又不想被覆盖掉,也就是说,我想要将每天备份的数据放在不同的档案中。
哇!
这真困扰啊?
难道要我每天去修改script?
不需要啊!
因为每天的『日期』并不相同,所以我可以将档名取成类似:
backup.20050802,不就可以每天一个不同档名了吗?
呵呵!
确实如此。
好了,接下来出个例子:
我想要建立三个空的档案,档名最开头由使用者输入决定,假设使用者输入filename好了,那今天的日期是2005/08/23,我想要以前天、昨天、今天的日期来建立这个档案,亦即filename_20050821,filename_20050822,filename_20050823,该如何是好?
[root@linuxscripts]#vish03.sh
#!
/bin/bash
#Program:
#Usercankeyinfilenametotouch3newfiles.
#History:
#2005/08/23VBirdFirstrelease
PATH=/bin:
/sbin:
/usr/bin:
/usr/sbin:
/usr/local/bin:
/usr/local/sbin:
~/bin
exportPATH
#1.让使用者输入文件名称,并取得fileuser这个变量;
echo-e"Iwilluse'touch'commandtocreate3files."
read-p"Pleaseinputthefilenamewhatyouwant:
"fileuser
#2.为了避免使用者随意按Enter,利用变量功能分析文件名是否有设定?
filename=${fileuser:
-"filename"}
#3.开始利用date指令来取得所需要的档名了;
date1=`date--date='2daysago'+%Y%m%d`
date2=`date--date='1daysago'+%Y%m%d`
date3=`date+%Y%m%d`
file1="$filename""$date1"
file2="$filename""$date2"
file3="$filename""$date3"
#4.将档名建立吧!
touch$file1
touch$file2
touch$file3
我透过一些简单的动作,这些动作都可以在bash那一章里面找到,包括小指令(`)的取得讯息、变量的设定功能、变量的累加以及利用touch指令辅助!
如果您